0%

Java虚拟机-类加载

一转眼2020年了,最近春节期间瘟疫肆虐,在家猫着无聊再学习一波JVM相关知识做一下笔记,争取年后能够成功跳槽。

在Java中类的加载是在程序运行中进行的,因此会对程序运行产生一些性能开销,但是增加了程序的灵活性。

类的加载是指将类的.class文件的二进制数据读入到内存中,将其放在运行时数据区的方法区中,然后在内存中创建一个java.lang.Class对象用来封装类在方法区内的数据。(规范并未规定Class对象放在哪里,hotspot将Class对象放在方法区中)

Java类加载的时机

加载 -> 连接 -> 初始化 -> 使用 -> 卸载 其中 连接又分为 “验证 -> 准备 -> 解析”三个阶段

符号引用:

直接引用:

主动使用:会对类进行初始化

1.创建类的实例

2.访问某个类或接口的静态变量,或者对该静态变量赋值

3.调用类的静态方法

4.反射

5.初始化一个类的子类

6.Java虚拟机启动时被标记为启动类的类(Java Test)

7.JDK1.7开始提供的动态语言支持 java.lang.invoke.MethodHandle实例的解析结果REF_getStatic,REF_putStatic,REF_invokeStatic句柄对应的类没有初始化,则初始化。

若常量在编译阶段可以确定会将其存入到调用这个常量的方法所在的类的常量池中,因此调用这个常量不会出发常量所在类的初始化。

若常量在编译阶段不确定其值不会放到常量池中,程序运行时会主动使用这个常量所在类,导致初始化。

对于数组实例,其类型为JVM在运行中动态生成的,表示为[Lcom.xxx.abc这种形式。动态生成的类型,其父类型就是Object。对于数组来说,JavaDoc经常将构成数组的元素为Component,实际上就是将数组降低一个维度后的类型。

Java类加载步骤

虚拟机参数

-XX:+TraceClassLoading 追踪类的加载信息并打印