本文参照尚硅谷-宋红康老师的视屏进行整理,仅供大家学习使用,如果侵权,请联系
下篇:https://blog.csdn.net/u010323860/article/details/107905310
1、下图是JVM加载class文件的整个过程;方法区、堆是所有线程共享的{一个JVM实例一份},垃圾回收也只会发生在这两块区域,而虚拟机栈、本地方法栈、程序计数器是一个线程一份。
2、类加载器Class Loader加载过程
Class Loader只负责class文件的加载,文件是否可以执行则有执行引擎来决定
2.1 (小)加载过程
(1)通过一个类的全限定名获取定义此类的二进制字节流
(2)将这个字节流所代表的静态存储结构转换为方法区[1.7的实现是老年代,1.8的实现是元空间]时数据结构
(3)内存中生成Class对象,作为方法区这个类的数据访问入口
2.2 链接
(1)验证:确保Class文件的信息符合JVM规范,保证正确性【文件格式、元数据、字节码、符号引用的验证】
(2)准备:为类变量分配内存并且设置该类变量的默认初始值【byte、short、int,long=0;float、double=0.0;boolean=false;包装类型为null】【注意:如果是final修饰的,就是一个常量,编译的时候已经确认了】;引用的实例变量也不会初始化
(3)解析:符号引用转换为直接引用
2.3 初始化
(1)执行类构造器方法<clinit>过程
自动收集所有类变量(也就是static修饰的)、静态代码块中的语句(如果没有这两块内容,不会生成cinit()方法),执行的顺序是按照源文件中定义的语句顺序执行的。【以下两种语句顺序不同,最后使用的a的值也不同】
(2)执行<init>构造器(也就是构造方法)[任何一个类内部至少存在一个类的构造器,默认的或者显示声明的]
执行构造方法中的代码内容
(3)如果一个类有父类,会先执行父类的<cinit>方法,然后在执行子类的<cinit>方法,而<cinit>一定会保证只有一个线程执行
2.4 类加载器分类
(1) 引导类加载器BootStrap ClassLoader
这个加载器是用C/C++实现的,所以JAVA中获取的时候是null;它加载java_home/jre/lib/rt.jar、resource.jar以及sun.boot.class.path路径下的类
(2) 扩展类加载器Extension ClassLoader【间接继承了classLoader】
JAVA语言实现的,加载jre/lib/ext下的类ÿ