对象组成、分配、强弱引用

java对象在内存中的布局:

对象头:

对象头中包含了MarkWord和类型指针,如果是数组对象,还会存在数组长度。

mark word是8字节,klassword压缩前8字节,压缩后4字节,一般都是取压缩后,实例数据如果是对象,或是引用,就是8个字节,最后还要加上对齐,必须是8的倍数。

Markword:

主要就是三个信息:锁信息(markword的最后两位决定上的是什么锁),hashcode,GC信息。

32位的对象头内MarkWord在默认情况下存储着对象的HashCode、分代年龄、是否偏向锁、锁标记位等信息

64位JVM中对象头内MarkWord的默认信息存储着HashCode、分代年龄、是否偏向锁、锁标记位、unused

MarkWord被设计成为一个非固定的数据结构,以便可以复用方便存储更多有效的数据,它会根据对象本身的状态复用自己的存储空间,除了上述列出的MarkWord默认存储结构外,还有如下可能变化的结构:

实例数据:

实例数据是指一个聚合量所有标量的总和,也就是是指当前对象属性成员数据以及父类属性成员数据。

对齐填充:

指针压缩:

压缩的是引用类型,比如object类型,原来是8字节,压缩后变成4字节,然后数组长度也变成4字节了。··

为什么32bit的指针支持寻址32GB?

JOL对象大小计算:

面试题:在java中创建一个Object对象会占用多少内存?

对象头大小markword+klassword(8)=16bytesObject类中没有定义任何属性,不存在实例数据。

如果开启指针压缩,只会有markword+klassword/2(4)=12bytes,类元指针被压缩一半.

会出现4bytes的对齐填充,最终不管是否开启了指针压缩,大小应该为16字节。

数组对象大小计算:

实例对象大小计算:

Java对象分配过程详解:

类加载检测:

全限定名为key,查找.class文件。确保当前要分配的对象所在的类已经加载完成了。

内存分配:
栈上分配:

只有不会逃逸的对象才能在栈上分配,栈上分配的对象可以随着栈帧的销毁而自动回收,不需要GC回收。

如果一个对象在方法内部创建并且没有被外部引用,JVM 可能会选择在栈上分配该对象,以减少堆的压力。

基于逃逸分析的优化:

标量替换:

TLAB分配:

如果TLAB分配成功,初始化操作就会提前到内存分配这一步。

分配过程:

年老代分配:
新生代分配:
小结:
初始化内存:
设置对象头:
执行<init>函数:

一个对象从生到死的历程:

对象最终会出现在Eden区(TLAB分配也是在Eden区,栈上分配不算),而线程栈中会出现一个指向对象的引用,之后需要使用该对象时,直接通过引用中的直接地址或句柄访问该块内存区域中的对象数据。

对象的访问方式:

在Java中对象都是通过reference访问的,主要分为两种访问方式,一种为句柄访问,另一种则为直接指针访问。

句柄访问:

直接指针访问:

小结:

GC时的对象移动与对象晋升:

动态对象年龄判定:

空间分配担保机制:

小结:

对象引用类型:

强引用类型:

GC是不会回收强引用对象的,要想回收只能显式的将对象引用清空,obj=null。

软引用类型:

弱引用类型:

student是个强引用,而id=1(student)这个对象与zhuZiWR弱引用对象存在联系,所以在GC时,是可以通过student指针,判定出zhuZiWR弱对象属于存活对象!因此,GC时不会回收它!

虚引用类型:

相关推荐
一叶飘零_sweeeet2 小时前
从 GC 频繁到毫秒级停顿:JVM 内存调优分代配比、晋升机制与架构策略全拆解
jvm
2401_853576502 小时前
使用PyTorch构建你的第一个神经网络
jvm·数据库·python
一叶飘零_sweeeet3 小时前
JVM GC 深度破局:G1 与 ZGC 底层原理、生产调优全链路实战
jvm·jdk17
qq_404265833 小时前
Django全栈开发入门:构建一个博客系统
jvm·数据库·python
moonlight03044 小时前
运行时数据区
jvm
m0_528174455 小时前
使用Python处理计算机图形学(PIL/Pillow)
jvm·数据库·python
一瓢西湖水5 小时前
CPU使用超过阈值分析
java·开发语言·jvm
不知名。。。。。。。。6 小时前
仿muduo库实现高并发服务器----EventLoop与线程整合起来
java·开发语言·jvm