JVM学习笔记(一)体系结构,类加载器,加载机制

JVM体系结构

  • JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
    引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
  • JVM体系结构简图:
    在这里插入图片描述
    JVM是介于java程序和操作系统之间的一个区域,由于是由C++编写,因此java又可以称为C++ - -,一个java文件编写完成后会被编译成class文件,然后经过类加载器进入运行时数据区。
    由于main方法在运行时会被压入栈底,每运行完一个方法会被弹出,因此垃圾回收不可能存在在栈里,而应该存在于堆中,由于方法区为特殊的堆,因此大部分性能调优都是对于堆的性能调优。

类加载器
类加载器的主要作用是加载类对象,将class文件加载为class类,如图所示:
                                      car.class
在这里插入图片描述
通过new的方式可以将class对象实例化为不同的实例化对象,实例化对象可以通过getClass的方式反射获得类对象,因此可以得出类是模板,而对象是具体的,所有的对象都是由同一个类实例化的。类的hashcode恒定,而每个对象各不相同。

测试

public class Car {
    public static void main(String[] args) {
        //类是模板,对象是具体的

        Car car1 = new Car();
        Car car2 = new Car();
        Car car3 = new Car();

        System.out.println(car1.hashCode());
        System.out.println(car2.hashCode());
        System.out.println(car3.hashCode());

        Class<? extends Car> car1Class = car1.getClass();
        Class<? extends Car> car2Class = car2.getClass();
        Class<? extends Car> car3Class = car3.getClass();

        System.out.println(car1Class.hashCode());
        System.out.println(car2Class.hashCode());
        System.out.println(car3Class.hashCode());

    }
}

测试结果
在这里插入图片描述
类加载器的种类

  1. 虚拟机自带的加载器
  2. 启动类(根)加载器:负责加载支撑JVM运行的位于jre/lib目录下的核心类库(例如:String、Object类),在虚拟机启动时就会加载完,以支撑虚拟机的运行。
  3. 扩展类加载器:负责加载支撑JVM运行的位于jre/lib/ext中的JAR包。由Java语言实现,父类加载器为null。
  4. 应用程序加载器:负责加载用户路径ClassPath下的类库。由Java语言实现,父类加载器为ExtClassLoader。

类加载器加载Class大致要经过如下8个步骤:

  1. 检测此Class是否载入过,即在缓冲区中是否有此Class,如果有直接进入第8步,否则进入第2步。
  2. 如果没有父类加载器,则要么Parent是根类加载器,要么本身就是根类加载器,则跳到第4步,如果父类加载器存在,则进入第3步。
  3. 请求使用父类加载器去载入目标类,如果载入成功则跳至第8步,否则接着执行第5步。
  4. 请求使用根类加载器去载入目标类,如果载入成功则跳至第8步,否则跳至第7步。
  5. 当前类加载器尝试寻找Class文件,如果找到则执行第6步,如果找不到则执行第7步。
  6. 从文件中载入Class,成功后跳至第8步。
  7. 抛出ClassNotFountException异常。
  8. 返回对应的java.lang.Class对象。

类加载机制

  1. 双亲委派机制
    双亲委派机制指的是类加载器(AppClassLoader)收到类加载的请求,会将这个请求向上委托给父类加载器去完成,一直向上委托。
    应用程序加载器-------扩展类加载器-------根加载器-------启动类加载器
    启动类加载器会检查是否可以加载这个类,如果可以加载就结束,使用当前加载器,否则抛出异常,通知子加载器进行加载,我们平时自定义的方法都是运行在应用程序加载器(AppClassLoader)上面的。
    启动类加载器-------根加载器-------扩展类加载器-------应用程序加载器
    当所有加载器都无法加载会通过native调用操作系统层的本地方法。
  2. 双亲委派机制的优势:采用双亲委派模式的是好处是Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次。其次是考虑到安全因素,java核心api中定义类型不会被随意替换,假设通过网络传递一个名为java.lang.Integer的类,通过双亲委托模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字的类,发现该类已被加载,并不会重新加载网络传递的过来的java.lang.Integer,而直接返回已加载过的Integer.class,这样便可以防止核心API库被随意篡改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值