从一无所知到无所不知————jvm系列(1)
目录
①一般在什么情况下会去加载一个类?也就是说,什么时候“.class”字节码文件中加载这个类到JVM内存里来?
前言
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,
它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
学习JVM能更深入的理解Java这门语言,能理解Java语言底层的执行过程,深入到字节码层次。
从本篇文章开始,我将带领大家先把JVM运行机制的整体脉络梳理清楚,然后不断的深入学习。
另外,本系列的更新进度一定会各位满意,因为我也即将进入急速成长状态,我们一起加油!
程序的运行
我们知道“.java”代码文件,编译成“.class”字节码文件,然后类加载器把“.class”字节码文件中的类给加载到JVM中,JVM就会基于自己的字节码执行引擎,来执行加载到内存里的我们写好类。那类的加载机制是怎么样的呢?类加载器和双亲委派机制又是什么呢?
1.JVM类加载机制
其实一个类从加载到使用要经过:加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载
①一般在什么情况下会去加载一个类?也就是说,什么时候“.class”字节码文件中加载这个类到JVM内存里来?
答:代码中用到这个类的时候。
②验证、准备、初始化
答:验证是校验你加载进来的“.class”文件,是否符合指定的规范,而准备是给验证后的类分配一定的内存空间、给里面的类(静态)变量(也就是static修饰的变量)分配内存空间、默认的初始值,解析阶段实际上是把符号引用替换为直接引用的过程。
③初始化
答:如“new ReplicaManager()”来实例化类的对象了,此时就会触发类的加载到初始化的全过程,把这个类准备好,然后再实例化一个对象出来;(包含“main()”方法的主类,必须是立马初始化的。)
注意,如果初始化一个类的时候,发现他的父类还没初始化,那么必须先初始化他的父类
2.类加载器和双亲委派机制
①启动类加载器
Bootstrap ClassLoader,负责加载我们在机器上安装的Java目录下的核心类
②扩展类加载器
Extension ClassLoader,Java安装目录下,有一个“libext”目录
这里面有一些类,就是需要使用这个类加载器来加载的,支撑你的系统的运行。
③应用程序类加载器
Application ClassLoader,这类加载器负责去加载环境变量所指定的路径中的类,
可以理解为去加载你写好的Java代码!
④自定义类加载器
自定义类加载器,可以根据自己的需求加载类。
⑤双亲委派机制
JVM的类加载器是有亲子层级结构的,就是说启动类加载器是最上层的,扩展类加载器在第二层,第三层是应用程序类加载器,最后一层是自定义类加载器。也就是说,需要加载一个类时,先由最上层找,找不到就由下一层找,最后找到需要加载这个类的类加载器,然后这个加载器就自己把这个类加载到内存里去了。这就是双亲委派模型,可以避免多层级的加载器结构重复加载某些类。
结尾
给大家留一个问题:什么场景下会用到自定义类加载器呢?