JVM类加载子系统(01)
类加载子系统的作用
- 类加载子系统负责从文件系统或者网络中加载class文件,class文件在文件开头有特定的文件标识
- classLoader只负责class文件的加载,execution engine负责是否可以执行
- 加载类的信息存放在一块方法区的内存空间。除了类的信息,方法区中还会存放运行时常量池的信息,可能还包括字符串常量和数字常量(这部分常量信息是class文件中常量池部分的内存映射)
类加载器classLoader角色
- class file 存在本地硬盘上,可以理解为设计师画在之上的模板,而最终这个模板在执行的时候是要加载到jvm当中来根据这个文件实例化出n个实例
- class file加载到jvm中,被称为dna元数据模板,放在方法区中
- 在class文件-》jvm-》dna元数据模板,此过程就要一个运输工具(类装载器 class Loader)。
类的加载过程
-
加载(loading)
-
通过一个类的全限定名获取此类的二进制字节流
-
将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
-
在内存中生成一个代表这个类的java.lang.class对象,作为方法区这个类的各种数据结构的访问入口,反射(JVM为每个加载的`class`及`interface`创建了对应的`Class`实例来保存`class`及`interface`的所有信息;
获取一个`class`对应的`Class`实例后,就可以获取该`class`的所有信息;
通过Class实例获取`class`信息的方法称为反射(Reflection);
JVM总是动态加载`class`,可以在运行期根据条件来控制加载class)
-
-
链接(ln)
-
验证:
- 目的在于确保class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机的自生安全
- 主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证
-
准备:
- 为类变量分配内存并设置该类变量的默认初始值,即零值
- 这里不包含用final修饰的static,因为final在编译时就分配了,准备阶段会显式初始化
- 这里不会为实例变量分配初始化,类变量分配在方法区中,而实例变量是会随着对象一起分配到java堆中
-
解析:
- 将常量池内符号引用转换为直接引用的过程
- 事实上,解析操作往往会伴随着jvm在执行完初始化之后再执行
- 符号引用就是一组符号来描述所引用的目标直接引用就是直接指向目标的指针,相对偏移量或一个间接定位到目标的句柄
- 解析动作主要针对类或接口,字段,类方法,接口方法,方法类型等,对应常量池中的constant_class_info,constant_fieldref_info,constant_methodref_info等
-
-
初始化
- 初始化阶段就是执行类构造器方法
()的过程 - 此方法不需定义,是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来
- 构造器方法中的指令按照语句在源文件中出现的顺序执行
()不同于类的构造器(关联:构造器是虚拟机视角下的 ()) - 若该类具有父类,jvm会保证子类的
()执行前,父类的 ()已经执行完毕 - 虚拟机必须保证一个类的<.clinit>()方法在多线程下被同步加锁
- 初始化阶段就是执行类构造器方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律