JVM-类与对象加载过程

89 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

JVM类加载过程

系统加载 Class 类型的文件主要三步:加载->链接->初始化

  • 连接过程又可分为三步:验证->准备->解析。

加载:

  • 根据全类名获取此类的二进制字节流
  • 将字节流所代表的静态存储结构转换为方法区的运行时数据结构
  • 在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口

ps:如果这个类的父类未被加载,会先加载父类

链接(分为三部分:验证、准备、解析)

  • 验证:验证文件格式、元数据、字节码、符号引用是否满足规范等

  • 准备:准备阶段是正式为静态变量(实例变量并没有)分配内存并设置默认值的阶段。(如果是加了final关键字,在编译器就设置好了初始值),否则,是在“初始化”阶段进行赋值的

  • 解析:解析阶段是虚拟机将常量池内的符号引用替换为直接引用(实际地址)的过程。

初始化:

  • 初始化阶段是执行初始化方法 ()方法的过程,是类加载的最后一步。

  • 这一步 JVM 才开始真正执行类中定义的 Java 程序代码(字节码)。


new 一个对象在堆中的历程

  1. 类加载检查:检测将要new对象的类是否经过“加载-链接-初始化”,如果没有,则执行类加载;如果有,就分配内存。

  2. 分配内存:JVM如何得知为该对象分配多少内存呢?(在类加载完成后就确定了)

  • 补充1:对象在内存中的布局可以分为 3 块区域:对象头实例数据对齐填充

    • 对象头包含两个信息:mark work + 类型指针(通过这个指针确定是哪个对象的实例)
    • 实例数据部分存储的是这个对象真正的有效信息
    • 对齐填充起到占位作用
  • 补充2:具体如何分配,有两种方法:
    • 指针碰撞(堆内存规整)
    • 空闲列表分配(堆内存不完整)
  1. 初始化零值
  2. 设置对象头
  3. 执行init方法,为对象初始化赋值