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

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时不会回收它!

虚引用类型:

相关推荐
滑德友8 小时前
jvm的metaSpace内存溢出问题排查
jvm
sinat_255487819 小时前
泛型:类·学习笔记
java·jvm·笔记·学习
闻哥10 小时前
Docker Swarm 负载均衡深度解析:VIP vs DNSRR 模式详解
java·运维·jvm·docker·容器·负载均衡
yangyanping2010819 小时前
Go语言学习之对象关系映射GORM
jvm·学习·golang
Barkamin1 天前
多线程简单介绍
java·开发语言·jvm
「QT(C++)开发工程师」1 天前
C++17三大实用特性详解:内联变量、std::optional、std::variant
jvm·c++
她说..1 天前
Java Object类与String相关高频面试题
java·开发语言·jvm·spring boot·java-ee
sinat_255487811 天前
泛型·学习笔记
java·jvm·数据库·windows·python
「QT(C++)开发工程师」1 天前
C++17三大实用特性详解:折叠表达式、结构化绑定与constexpr if
jvm·c++
minji...1 天前
Linux 多线程(五)用C++语言以面向对象方式封装线程
linux·运维·服务器·网络·jvm·数据库