兄弟们感兴趣的话,在 JVM 篇有对 对象的详细介绍:对象实例化内存布局
运行时元数据(对象标记)Mark World,包括:
如果是数组的实例部分还包括数组的长度,
在64位系统中,Mark Word占了8个字节,类型指针占了8个字节,一共是16个字节(不考虑压缩指针)
mark word(64位)分布图,对象布局、GC回收和后面的锁升级就是对象标记MarkWord里面标志位的变化
类型指针(类元数据)Klass Pointer
对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
存放类的属性(Field)数据信息,包括父类的属性信息,这部分内存按4字节对齐。
虚拟机要求对象起始地址必须是8字节的整数倍。
填充数据不是必须存在的,仅仅是为了字节对齐,这部分内存按8字节补充对齐。
class Customer{int i ;boolean flag;
}
Customer对象头占用16个字节,i 占有 4 个字节,boolean占用 1 个字节,总共 21 个字节,但是 jvm 要求对象占用的字节必须为 8 的倍数,因此填充为 24 个字节。
显示的表示对象内存布局
JOL官网
增加依赖:
org.openjdk.jol jol-core 0.9
代码:
public class JOLTest {public static void main(String[] args) {// //VM的细节详细情况// System.out.println(VM.current().details());// //所有的对象分配的字节都是8的整数倍。// System.out.println(VM.current().objectAlignment());Object o = new Object();System.out.println( ClassLayout.parseInstance(o).toPrintable());}
}
输出结果:
类型指针占用 4 字节,是因为默认开启了 压缩指针。
查看自定义类的内存布局:
public class JOLTest {public static void main(String[] args) {Customer customer = new Customer();System.out.println( ClassLayout.parseInstance(customer).toPrintable());}
}class Customer{int i ;boolean flag ;
}
输出结果:
GC年龄采用4位bit存储,最大为15,
例如MaxTenuringThreshold参数默认值就是15
如果设置 阈值大于 15,就会报错
jvm 中默认开启了 压缩指针。主要是为了节省内存空间
默认开启压缩指针,对象内存情况:
对象标记 8 个字节,类型指针 4 个字节,对齐填充 4 个字节 = 16 个字节
关闭压缩指针,对象内存情况:-XX:-UseCompressedClassPointers
对象标记 8 个字节,类型指针 8 个字节就对应上了。
各位彭于晏,如有收获点个赞不过分吧…✌✌✌
gongzhonghao 回复 [JUC] 获取MarkDown笔记
上一篇:网络流量异常检测综述
下一篇:【自然语言处理概述】99乘法表