JVM把class文件加载到内存里面,并对数据进行校验、准备、解析和初始化,最终可以被造成被JVM能够直接使用的Java类型的过程。java
连接就是将Java类的二进制代码合并到java的运行状态中的过程。数组
初始化阶段是执行类构造器<clinit>()方法。在类构造器方法中,它将由编译器自动收集类中的全部类变量的赋值动做(准备阶段的a正是被赋值a)和静态变量与静态语句块static{}合并,初始化时机后续再聊。安全
正常使用。数据结构
GC把无用对象从内存中卸载。布局
一、类加载时机测试
当应用程序启动的时候,全部的类会被一次性加载吗?估计你早已知道答案,固然不能,由于若是一次性加载,内存资源有限,可能会影响应用程序的正常运行。那类何时被加载呢?例如,A a=new A(),一个类真正被加载的时机是在建立对象的时候,才会去执行以上过程,加载类。当咱们测试的时候,最早加载拥有main方法的主线程所在类。spa
二、类初始化时机线程
主动引用(发生类初始化过程)指针
被动引用(不会发生类的初始化)code
1 public class ClassLoaderProduce { 2 static int d=3; 3 static{ 4 System.out.println("我是ClassLoaderProduce类"); 5 } 6 public static void main(String [] args){ 7 int b=0; 8 String c="hello"; 9 SimpleClass simpleClass=new SimpleClass(); 10 simpleClass.run(); 11 } 12 } 13 14 class SimpleClass{ 15 static int a=3; 16 static{ 17 a=100; 18 System.out.println(a); 19 } 20 21 public SimpleClass(){ 22 System.out.println("对类进行加载!"); 23 } 24 25 public void run(){ 26 System.out.println("我要跑跑跑!"); 27 } 28 }
步骤一:装载ClassLoaderProduce类,在方法区生成动态数据结构(静态变量、静态方法、常量池、类代码),而且在堆中生成java.lang.Class对象;而后进行连接
步骤二:初始化:把static{}与静态变量合并存放在类构造器当中,对静态变量赋值。 1-5行执行完毕。
步骤三:执行main方法,首先在栈里面生成一个main方法的栈祯,定义变量b、c,注意此处的变量b、c存储的常量池存储的变量的地址,如图所示。
步骤四:建立SimpleClass对象;跟上面步骤相似:加载-连接-初始化。而后,调用run()方法的时候,它会经过classLoader局部变量的地址寻找到类的class对象而且调用run()方法