bilibili-深入理解JVM 虚拟机 学习笔记
P3 _深入理解JVM课程大纲分析与工具使用(3)
R大 iteye
工具
jconsole
jvisualvm
命令
jmap
学习目录大纲
P4 _类加载器深入解析与阶段分解(4)
- 类加载
在java代码中,类
的加载、连接和初始化过程都是在程序运行期间
完成的。
提供了更大的灵活性,提供了更多的可能性
- 类加载器
- 类加载器与程序的生命周期
- JVM 生命周期的结束
- 程序正常执行完成
- 执行 System.exit() 方法
- 程序执行过程中遇到异常和错误而异常终止
- 操作系统出现错误导致 JVM 进程终止
- 类的
加载
查找并加载类的二进制数据
例如:将本地磁盘上的 class 文件加载到内存中;
- 类的
连接
- 验证
- 确保被加载类的正确性
- 是否被恶意篡改
- 格式是否符合java虚拟机规范
- 准备
- 为类的
静态变量
分配内存,并将其初始化为默认值
- public static int a = 100;
- 此阶段只会将 a 变量初始化为 int 的默认值 0
- 为类的
- 解析
- 将类中的
符号引用
转换为直接引用
- 符号引用
- 没有实际的指针位置,只有一个符号:Student stu;
- 直接引用
- 对象引用的指针位置,stu 的对象指针位置
- 将类中的
- 类的
初始化
为类的静态变量赋予正确的初始化值,如上述 a 变量赋值为 100
- 类的
使用
和卸载
- 使用
- 使用类创建对象
- 使用对象的属性和方法等
- 卸载
- 将类的数据结构从jvm中销毁掉
- 类卸载后,不能再使用该类创建对象
- 开发人员很少使用
- OSGi
P5 _类的加载连接与初始化过程详解(5)
Java 程序对类的使用方式
- 主动使用
- 创建类的
实例
(类的对象) - 访问类或接口的静态变量
- 对类或接口的
静态变量
进行赋值 - 调用类的
静态方法
- 反射 Class.forName(“xxx.Y”)
- 初始化一个类的子类
- class A{}
- class B extends A{}
- 初始化 B 时,会初始化 A
- Java虚拟机启动时被标明为启动类的类(包含 main 方法)
- jdk1.7提供了动态语言的支持
- java.lang.invoke.MethodHandle 实例的解析结果 REF_getStatic,REF_putStatic,REF_invokeStatic 句柄对应的类没有初始化,则初始化
- 创建类的
- 被动使用
- 除了以上7种主动使用外,其他都是被动使用,都不会导致
类的初始化
操作- 但
可能
会执行类的加载
和连接
操作
- 但
- 除了以上7种主动使用外,其他都是被动使用,都不会导致
所有的Java虚拟机实现(HotSpot、J9等等)必须在每个类或接口被Java程序“
首次主动使用
”时才初始化他们;
助记符:
getstatic
putstatic
invokestatic
类的加载
类的加载是指将类的 .class 文件中的二进制数据
读入到内存中,将其放在运行时数据区
的方法区内,然后在内存中创建一个 java.lang.Class 对象用来封装类在方法区内的数据结构(java虚拟机规范并未说明Class对象应放到哪里,HotSpot虚拟机将其放在了方法区中)。
以上表述是在 JDK1.7 及之前的版本; JDK1.8 中,虚拟机移除了方法区,新增了元数据区。
加载 .class 文件的方式:
- 从本地系统中直接加载
- 从网络下载 .class 文件
- 从 zip、jar 等归档文件中加载 .class 文件
- 从专用数据库中提取 .calss 文件
- 将 .java 源文件动态编译成 .class 文件
- 动态代理
- jsp -> Servlet