本文已参与「新人创作礼」活动,一起开启掘金创作之路。
JVM类加载过程
系统加载 Class 类型的文件主要三步:加载->链接->初始化。
- 连接过程又可分为三步:验证->准备->解析。
加载:
- 根据全类名获取此类的二进制字节流
- 将字节流所代表的静态存储结构转换为方法区的运行时数据结构
- 在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口
ps:如果这个类的父类未被加载,会先加载父类
链接(分为三部分:验证、准备、解析)
-
验证:验证文件格式、元数据、字节码、符号引用是否满足规范等
-
准备:准备阶段是正式为静态变量(实例变量并没有)分配内存并设置默认值的阶段。(如果是加了final关键字,在编译器就设置好了初始值),否则,是在“初始化”阶段进行赋值的
-
解析:解析阶段是虚拟机将常量池内的符号引用替换为直接引用(实际地址)的过程。
初始化:
-
初始化阶段是执行初始化方法 ()方法的过程,是类加载的最后一步。
-
这一步 JVM 才开始真正执行类中定义的 Java 程序代码(字节码)。
new 一个对象在堆中的历程
-
类加载检查:检测将要new对象的类是否经过“加载-链接-初始化”,如果没有,则执行类加载;如果有,就分配内存。
-
分配内存:JVM如何得知为该对象分配多少内存呢?(在类加载完成后就确定了)
-
补充1:对象在内存中的布局可以分为 3 块区域:对象头、实例数据和对齐填充。
- 对象头包含两个信息:mark work + 类型指针(通过这个指针确定是哪个对象的实例)
- 实例数据部分存储的是这个对象真正的有效信息
- 对齐填充起到占位作用
- 补充2:具体如何分配,有两种方法:
- 指针碰撞(堆内存规整)
- 空闲列表分配(堆内存不完整)
- 初始化零值
- 设置对象头
- 执行init方法,为对象初始化赋值