# jAVA 初识jvm(三)

jAVA 初识jvm(三)

类加载器子系统

1.类加载器子系统负责从文件系统或者网络中加载class文件,class文件要求具有特定的文件标识。
2.ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。
3.加载的类信息存放于一块成为方法区的内存空间。还会存放运行时常量池.
如图为引用网图展示一个类的加载过程:
# jAVA 初识jvm(三)_第1张图片

加载阶段(Loading)

1.通过一个类的全限定名获取此类的二进制流。
2.将字节流代表的静态存储结构转换为运行时的数据结构。
3.在内存中生成一个代表这个类的Java.lang.Class对象。

链接阶段(Linking)

验证

1.确保Class文件的字节流中的信息符合虚拟机的要求。保证被加载类的正确性。不会危害虚拟机自身安全。

准备

1.为类变量分配内存,设置初始值及零值。
2.这里不包含final修饰的常量,final修饰的常量在编译的时候进行初始化。
3.这里不会为实例变量初始化,实例变量随着对象一起分配到Java堆中

解析

1.将常量池中的符号引用转换为对应的直接引用。
2.符号引用就是一组符号,描述所引用的目标。

初始化阶段(Initialization)

执行类构造器方法不同于类的构造方法,此方法不需要编译。构造器方法中指令的语句按照源文件中的顺序进行执行的。子类的执行晚于父类的执行。子类加载之前保证父类加载。虚拟机必须保证一个类的()在多线程下同步加锁。

一个类只能加载一次

public class DeadThreadTest1 {
    public static void main(String[] args) {
        Runnable r=()->{
            System.out.println(Thread.currentThread().getName()+"开始");
            DeadThread deadThread=new DeadThread();
            System.out.println(Thread.currentThread().getName()+"结束");
        };
        new Thread(r,"线程1").start();
        new Thread(r,"线程2").start();
    }
}
class DeadThread{
    static {
        if(true){
            System.out.println(Thread.currentThread().getName()+"初识化当前的类");
            while (true){
            }
        }
    }
}

# jAVA 初识jvm(三)_第2张图片

类加载器分类

  • Jvm支持两种:引导类(Bootstrap Class Loader)、自定义类(User Defined Class Loader)
  • 所有派生于ClassLoader类的加载器划分为自定义类。

主要分为两类如网络示意图:不是继承关系,是包含关系
# jAVA 初识jvm(三)_第3张图片
获取当前类的加载器类型示例代码:java的核心类库都是使用引导类加载器进行加载的

public static void main(String[] args) {
    //获取系统类加载器
    ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    System.out.println(systemClassLoader);
    //获取其上层:扩展类加载器
    ClassLoader classLoader=systemClassLoader.getParent();
    System.out.println(classLoader);
    //获取其上层:获取不到其上层引导类加载器
    ClassLoader bootstrapLoader=classLoader.getParent();
    System.out.println(bootstrapLoader);
    //对于用户自定义类:默认使用系统类加载器来加载
    ClassLoader classLoader1 = ClassLoaderTest1.class.getClassLoader();
    System.out.println(classLoader1);
    //String使用引导类加载器加载。--->java的核心类库都是使用引导类加载器进行加载的
    ClassLoader classLoader2 = String.class.getClassLoader();
    System.out.println(classLoader2);
}

你可能感兴趣的:(Java)