本博客用来自我总结,不做学习之用,防止误人子弟。
想了解透彻还得看这篇 https://www.cnblogs.com/kaleidoscope/p/9629156.html

  1. 加载
    1. 在类加载之初,首先加载的是 Main方法的类。
    2. 首先,会读取类编译之后的 .class 文件,将其中的二进制编码按照 ClassFile 转化为程序执行的数据结构。
    3. 然后,会根据加载的文件中的类的信息,在 堆 中的方法区(元空间,永久代)内创建这些类的信息,包括类名,变量名,会将一些默认值放在常量池内,然后根据这些信息会在 堆 中创建对应每个类的 Class 对象。
  2. 链接
    1. 首先,会根据读取的内容判断这个程序是否符合 JVM 编码规范以及是否具有安全隐患。
    2. 其次,会初始化类内部的静态代码块或者静态变量(Static),然后会给其中的静态变量赋值,赋值为该类型的默认值。
    3. 最后,将常量池内的符号引用改为其内存地址的引用。
  3. 初始化
    1. 首先,执行类构造器 clinit 方法,clinit 方***在类编译期间自动收集其变量赋值以及静态代码块代码合并。(这里的 clinit 是用来初始化类的不是方法的构造函数)
    2. 其次,当初始化一个类的时候,如果其父类还没有初始化,则先初始化其父类。
    3. JVM 会保证 clinit 执行的线程安全问题(保证正确加锁以及线程同步)。
  4. 然后这里就会依次序执行类中的方法,首先会将 main 方法入栈,然后会将一些常量,定义的一些方法压栈,等到这些常量使用完毕或者方法调用完毕,就会执行出栈过程。如果栈为空了就表示程序执行完毕。

浅见,欢迎补充。