面试准备 --- JVM类加载机制

为了春招,系统地复习一下Java相关的知识,应该不会写源码解析,完全是给自己看的,如果足够幸运,有幸进入大厂,重新写下给别人看的

注意点

  • 类从被加载到被卸载的生命周期如下: 加载 -> (验证 -> 准备 -> 解析)(连接) -> 初始化 -> 使用 -> 卸载 ; 虽然写下来是这样的的顺序,但是不同阶段间可能交叉进行,即一个阶段还未完成,另一个就已经开始.而解析这个阶段却有例外,在某些情况下,解析可以再初始化后进行,如果了解了解析这个阶段是干什么的后,其实就明白初始化后解析就是Java中的动态绑定.

  • 加载

    • 该阶段主要做三件事:
      • 通过一个类的全限定名找到此类的二进制字节流
      • 将字节流所代表的静态存储结构转换为方法区的运行时数据结构
      • 在内存中生成一个这个类的java.lang.Class对象,这个对象不放在堆中,而是在方法区中,主要作为第二步生成的各种数据结构的访问入口.
    • 类加载机制
      • 主要说一下如何将字节流转换成Class对象,也就是我们经常说的类加载器,这里就要说很多,我之前写过一个关于双亲委托机制的博客,这里
  • 验证

    • 这个阶段就是为了确保Class文件的字节流中包含的内容符合当前虚拟机的要求,不会危害到虚拟机自身的安全.详细的我没有深入了解过.
  • 准备

    • 这个阶段主要是为类中静态变量设置初始值,注意,并不是程序中的初始值,而是该类型的默认值,即整数置0,而不是程序中的.但是还是有例外.如果这个静态变量是用final修饰的,就会被置程序中的初始值.
  • 解析

    • 解析这个阶段就是将常量池中的符号引用转变为直接引用,其实我并不是很理解符号引用,我只是当做变量和方法和类之间的绑定,这个理解并不正确,只是暂且如此.
  • 初始化

    • 到了这一步,其实才真正的和用户相关,因为之前的阶段我们除了可以指定自定义类加载器,其余都是虚拟机自主的,
    • 这一步就会对准备阶段"初始化"的静态变量进行真正的初始化,赋予程序中的初始值.
    • 这个阶段其实是执行类构造器<clinit>方法的过程,这个方法会收集所有类变量和静态语句块
  • 类加载时机,这是我之前的疑惑,一直没找到准确的描述,最近在书上才找到.Java虚拟机其实并没有对于什么时候开始加载这个阶段做严格要求,完全交给虚拟机自己把握.

  • 类初始化时机,上面说到Java没有对加载时机做要求,但是对于初始化却做了严格要求,即主动使用一个类时进行初始化,有主动自然由被动,详情参看主动使用和被动使用,当然了,初始化前一定要进行加载,验证,准备阶段.

  • 还需要注意的一点是静态内部类,静态内部类和静态属性和静态方法还是有一些不同.
    先看一些相同的,从主动使用和被动使用的博客中可以看到,访问静态属性和静态方法都属于主动使用,会触发类的初始化,同样的,访问一个类的静态内部类也会引起该类的初始化,而且是先外部后内部.
    不同的,其实也不能算是不同,这么说吧,如果外部的类被初始化时并不会触发静态内部类的初始化.

猜你喜欢

转载自blog.csdn.net/qq_36865108/article/details/86661322