计算前提
JDK 版本,不同版本的类可能会有变化
要区分是 32bit 还是 64bit 系统
是否开启压缩指针(默认开启,指针为 4Byte,否则为 8Byte)
是否数组,数组对象头多了一个长度值,占 4Byte
计算方法对象所占内存 = 对象头 + 所有域 + 填充
其中,若域为另一个对象,即非基本类型,则需递归计算
对象头分为3部分:
mark word:同步状态、GC状态、hashcode 等
klass pointer: 指向本身的类对象
数组类型的长度
_mark | _kclass | Array Length | |
---|---|---|---|
32bit | 4 | 4 | 4 |
64bit | 8 | 8 | 4 |
64+comp | 8 | 4 | 4 |
https://mechanical-sympathy.blogspot.com/2011/07/false-sharing.html
http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html
// 32 bits: // -------- // hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object) // JavaThread*:23 epoch:2 age:4 biased_lock:1 lock:2 (biased object) // size:32 ------------------------------------------>| (CMS free block) // PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object) // // 64 bits: // -------- // unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object) // JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object) // PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object) // size:64 ----------------------------------------------------->| (CMS free block) // // unused:25 hash:31 -->| cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && normal object) // JavaThread*:54 epoch:2 cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && biased object) // narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object) // unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/87ee5ee27509/src/share/vm/oops/markOop.hpp#l29
对象的域在内存中的顺序:域的顺序并不是在类中定义的顺序,而是经过了调整;每个对象都是 8Byte 对齐的,不是倍数的话会在最后填充,具体顺序如下:
doubles (8) and longs (8)
ints (4) and floats (4)
shorts (2) and chars (2)
booleans (1) and bytes (1)
references (4/8)
repeat for sub-class fields
https://zeroturnaround.com/rebellabs/dangerous-code-how-to-be-unsafe-with-java-classes-objects-in-memory/5/
不同域的大小Bytes | |
---|---|
boolean | 1 |
byte | 1 |
char | 2 |
short | 2 |
int | 4 |
float | 4 |
long | 8 |
double | 8 |
reference | 4 |
64bit 压缩指针 JDK8 中 String s = "abc",对象 s 的大小: 48Bytes
注意:不同版本的 JDK String 类的域不同,比如 JDK6 中有 offset、count,JDK7 中有 hash32。
具体验证可以使用 jol 库:
http://openjdk.java.net/projects/code-tools/jol/
System.out.println(GraphLayout.parseInstance("abc").toPrintable()); ==> java.lang.String@2ff4acd0d object externals: ADDRESS SIZE TYPE PATH VALUE 795707020 24 java.lang.String (object) 795707038 24 [C .value [a, b, c]
Welcome to my Blog
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/68297.html
摘要:对于不同的实现,对象占用的内存空间大小可能不尽相同,本文主要分析中的情况,实验环境为位系统,使用进行结论验证。内存占用这里分析一个只有一组键值对的结构如下首先分析本身的大小。 本文深入分析并验证了不同Java对象占用内存空间大小的情况。对于不同的jvm实现,Java对象占用的内存空间大小可能不尽相同,本文主要分析HotSpot jvm中的情况,实验环境为64位window10系统、JD...
摘要:加载图的机制是什么,为何不会内存泄漏自定义可拖动的显示高清大图的技术博客大总结提供一个设置图片的入口,里面去获得图片的真实的宽度和高度,以及初始化我们的重写,在里面根据用户移动的手势,去更新显示区域的参数。 目录介绍 7.0.0.1 加载bitmap图片的时候需要注意什么?为何bitmap容易造成OOM?如何计算Bitmap占用内存? 7.0.0.2 如何理解recycle释放内存问...
摘要:本文详细描述了堆内存模型,垃圾回收算法以及处理内存泄露的最佳方案,并辅之以图表,希望能对理解内存结构有所帮助。该区域也称为内存模型的本地区。在中,内存泄露是指对象已不再使用,但垃圾回收未能将他们视做不使用对象予以回收。 本文详细描述了 Java 堆内存模型,垃圾回收算法以及处理内存泄露的最佳方案,并辅之以图表,希望能对理解 Java 内存结构有所帮助。原文作者 Sumith Puri,...
摘要:第一个大陡坡是应用发布,老年代内存占比下降,很正常。但此时老年代内存使用占比。因为后期并不会引发。可以看出,由于到达时候,触发了一次和一次。但触发时,占比并没用明显的规律。得出,扩容导致这个说法,其实是不准确的。 转载请注明原文链接:https://www.jianshu.com/p/468... 某天早上,毛老师在群里问「cat 上怎么看 gc」。 showImg(https://...
摘要:由于的自动内存管理系统要求对象起始地址必须是字节的整数倍,换句话说,就是对象的大小必须是字节的整数倍。对象大小计算要点在位系统下,存放指针的空间大小是字节,是字节,对象头为字节。静态属性不算在对象大小内。 jvm系列 垃圾回收基础 JVM的编译策略 GC的三大基础算法 GC的三大高级算法 GC策略的评价指标 JVM信息查看 GC通用日志解读 jvm的card table数据结构 Ja...
阅读 3201·2021-11-24 10:43
阅读 4159·2021-11-24 10:33
阅读 3707·2021-11-22 09:34
阅读 2093·2021-10-11 10:58
阅读 3644·2021-10-11 10:58
阅读 831·2021-09-27 13:36
阅读 3535·2019-08-30 15:54
阅读 2910·2019-08-29 18:41