1. JVM是什么?
虚拟机,一种能够运行java字节码的虚拟机。
2. JVM的基本结构
- 类加载器
加载.class文件到内存. - 内存结构
运行时的数据区 - 执行引擎
执行内存中的.class文件,输出执行结果(包括GC:垃圾收集器), GC在后面一节会提到 - 本地方法的接口
- 本地方法库在这里插入图片描述
3. 类加载的过程
- 加载
将.class文件从磁盘读到内存. - 连接
- 验证: 验证字节码文件的正确性.
- 准备: 给类的静态变量分配内存, 并赋予默认值.
- 解析: 类加载器装入类所引用的其他所有类.
- 初始化
为类的静态变量赋予正确的初始值,上述的准备阶段为静态变量赋予的是虚拟机默认的初始值, 此处赋予的才是程序编写者为变量分配的真正初始值, 执行静态代码块. - 使用
- 卸载
4. 类加载器的种类
- 启动类加载器(c语言编写的)–>爷爷
负责加载jre的核心类库,如JRE目标下的rt.jar,charsets.jar等。 - 扩展类加载器(Java语言编写的)–>父亲
负责加载jre扩展类库。 - 系统类加载器(Application ClassLoaderJava语言编写的)–>儿子
负责加载我们自定义的类.
5. 类加载机制(类通过哪些类加载器加载呢?)
-
全盘负责委托机制: 会使用当前类的类加载器去加载关联类
举个栗子(例子)–>A类, B类, A类中引用了B类
如何加载?
A类是自定义的类,所以JVM会使用系统类加载器去加载A类. 那么使用哪个加载器去加载B类呢?
要判断有没有手动指定类加载器去加载B类如果没有手动指定类加载器,将使用A类的加载器去加载B类.
如果手动指定了类加载器,将使用指定的加载器去加载B类. -
双亲委派机制: 指先委托父类加载器寻找目标类,在找不到的情况下再在自己的路径中查找并载入目标类。
-
先去找系统类加载器,判断这个类有没有被加载过?
-
如果没有,就会去找父类(扩展类加载器)
-
扩展类加载器会判断,这个类有没有被加载?
-
如果没有,就会继续找父类(启动类加载器)
-
启动类加载器会判断, 这个类有没有被加载过?
-
启动类加载器没有父类, 所以会判断这个类是不是它负责加载的? 是就加载
-
如果启动类加载器判断这个类不是他负责加载,返回到扩展类加载器,扩展类加载器会判断这个类是不是它负责加载的?是就加载.
-
如果扩展类加载器判断这个类不是他负责的,返回到系统类加载器, 系统类加载器会判断是不是它负责加载的, 是就加载
到这里肯定有一个类加载器负责加载这个类.