基本结构
对操作系统的抽象,通过应用 层来实现语言的平台无关的特性,能解释编译运行class字节码文件
Preview
模块组成
- Class Loader:类加载器,用于将编写好的Java代码加载到JVM中。
- Execution Engine:执行引擎,负责将字节码转换成机器指令,让计算机执行程序。
- Memory:内存区域,用于存储程序运行时所需要的数据
- Garbage Collector:垃圾回收器,负责回收不再使用的内存空间。
- JNI:Java Native Interface:允许Java代码与本地代码交互。
对象的创建
- 在常量池判断是否已经类加载,如果没有加载,先执行 类加载
- 为对象分配堆内存
- 所需内存的大小在类加载完成 后便可完全确定
- 通过指针碰撞(Bump-the-pointer)或空闲列表(Free-list)方式来分配内存
- 将分配到的内存空间(但不包括对象头)都初始化为零值,包括对象的实例变量。这一步保证对象在Java语言级别看到的默认值。
- 设置对象头,其中包括对象的类型信息(指向类的元数据)、GC信息、锁信息等。
- 执行init,即调用对象的构造方法(Constructor),进行进一步的初始化。构造器可以有参数,也可以通过重载定义多个
对象的内存布局
-
对象头(Header): 包括对象的类型信息(Class Pointer)和同步信息(Mark Word)。
- Mark Word(标记字段): 存储对象的运行时数据,如哈希码、锁状态、GC分代年龄等信息,是动态的空间,根据标志位存储不同的东西。
存储内容 标志位 状态 对象哈希码 01 未锁定 指向锁记录的指针 00 轻量级锁定 指向重量级锁的指针 10 膨胀,重量级锁定 空,不需要信息 11 GC标记 偏向线程ID,偏向时间戳,对象分代年龄 01 可偏向 - Class Pointer(类型指针): 指向对象所属类的元数据信息,即对象的类的Class对象。
-
实例数据(Instance Data): 包括实例变量的数据。
- 实例数据是对象中各个实例变 量的具体值。它们按照定义的顺序依次存储在对象的内存中。实例数据的布局取决于类的定义,在内存中按照定义的顺序依次存储。
-
对齐填充(Padding): 确保对象的大小是字节的整数倍,通常是8字节对齐。
- 没有实际意义,占位符的作用,由于硬件的要求,Java对象的大小通常是8字节对齐的,即对象的大小必须是8字节的整数倍。
- 为了保证对象的大小满足这个要求,有时候需要对实例数据进行填充,即在实例数据的末尾添加额外的字节使得对象的总大小达到8字节对齐。