Java对象大小:size和retained size
最近看到网上很多文章讲如何计算java对象的大小(size),很多观点不敢苟同。
这是其中一篇比较靠前的文章,写的也比较全面:
http://blog.csdn.net/iter_zc/article/details/41822719/
认真拜读了一下,有些收获,也有一些疑问。
按照“字节对齐”的理论,所有java对象的大小应该是8的整数倍,且对象头会有8+4=12个字节
下面写了两个类进行验证:

代码中SizeOfAgent是文中讲到的通过Instrumentation.getObjectSize()计算对象大小的方法
两个对象大小确实是8的倍数,其中b.size的运行结果跟其文中讲到是一样的
b.size = 8(_mark) + 4(oop指针) + 4(i1) + 4(i2) + 1(b1) + 1(b2) + 1(b3) + 1(padding) + 4(str) + 4(obj) = 32
但a.size就不对了,按照该理论
a.size= 8(_mark) + 4(oop指针) + 4(a) + 4(strB) + 4(padding) = 24
但实际运行结果是16,带着疑惑去看了一下官方文档:

可以看到,Instrumentation.getObjectSize()返回的是一个估算值。
我认为,既然是估算值,对于学术研究,没什么参考性。其实Java对象大小从概念开始就比较复杂,要不然的话,干脆提供c++那样的sizeOf用就行了,还用整个javaagent来包装Instrumentation来提供
Java对象大小应该从两方面去理解:(1)其本身的大小-size (2)其占用堆的大小-retained
用JVisualVm提供的Heap dump可以来看这两个数值,以下是这两个对象在JVisualVm显示的size

没找到理论依据,我估计是这么计算的
a.size = 8(对象头) + 4(a) + 4(strB) = 16
b.size = 8(对象头) + 4(str) + 4(i1) + 1(b1) + 1(b2) + 4(i2) + 4(obj) + 1(b3) = 27
这个算法总结为 size(object) = 8 + sum(sizeField(x)), x为object所有字段
(1)8是对象头,具体是什么,没研究过
(2)sizeField对于简单类型的字段(byte/short/int/long...),返回(1/2/4/8...),对于对象类型的字段,返回4(可以理解为一个指针地址的大小)
读者可以写些其他结构来验证这个公式
那么retained又怎么算呢,首先看下这个单词的解释
The retained size for an object is the quantity of memory this objects preserves from garbage collection
retained表示一个对象无法被垃圾回收的内存大小,反过来讲就是它被回收后,能释多少内存
同一种类型的对象,其size必然是相同的,但retained size不一定相同
这个很好理解,size只跟类型相关,retained size 跟数据相关,一个对象里面有个String字段是null,另外一个对象里面该字段存的“abc”,内存占用必然不相同
注意:不能简单地认为retained size就是对象本身的size+所有字段的retained size,因为对象里面的一个字段可能被其他对象在引用。
下面来看一段代码

申明了两个类A和B,各有两个对象,通过JVisualVm来看他们的Size和Retained Size(中文版里面叫保留的大小,吐槽一下JDK自带的工具的中文翻译很稀烂):



结论:
- size(object) = 8 + sum(sizeField(x)); x为object所有字段
- sizeField(field) = isPrimitive ? primitiveSize(field) : 4;
- retained(object)= size(object) + sum(retained(x)) ; if x仅被object引用
Java对象大小:size和retained size的更多相关文章
- Shallow Size 和 Retained Size
所有包含Heap Profling功能的工具(MAT, Yourkit, JProfiler, TPTP等)都会使用到两个名词,一个是Shallow Size,另一个是 Retained Size. ...
- Java对象大小计算
这篇说说如何计算Java对象大小的方法.之前在聊聊高并发(四)Java对象的表示模型和运行时内存表示 这篇中已经说了Java对象的内存表示模型是Oop-Klass模型. 普通对象的结构如下,按64位机 ...
- 两种计算Java对象大小的方法
之前想研究一下unsafe类,碰巧在网上看到了这篇文章,觉得写得很好,就转载过来.原文出处是: http://blog.csdn.net/iter_zc/article/details/4182271 ...
- Java虚拟机14:Java对象大小、对象内存布局及锁状态变化
一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...
- Java虚拟机18:Java对象大小、对象内存布局及锁状态变化
一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...
- java调优随记-java对象大小
在java中,基本数据类型的大小是固定.但是java对象的大小是不固定的,需要通过计算. 在java中,一个空对象(没有属性和方法的对象)在堆中占用8byte,比如 Object obj = new ...
- java对象大小
Java对象的内存布局:对象头(Header),实例数据(Instance Data)和对齐填充(Padding) 对象头在32位系统上占用8B,64位系统上占16B. 无论是32位系统还是64位系统 ...
- GC之二--GC是如何回收时的判断依据、shallow(浅) size、retained(保留) size、Deep(深)size
回到问题“为何会内存溢出?”. 要回答这个问题又要引出另外一个话题,既什么样的对象GC才会回收? 一.对象存活方式判断方法 在上一篇文章<GC之一--GC 的算法分析.垃圾收集器.内存分配策略介 ...
- jvm详情——2、Java对象在jvm中的大小
Java对象的大小 基本数据的类型的大小是固定的,这里就不多说了.对于非基本类型的Java对象,其大小就值得商榷.在Java中,一个空Object对象的大小是8byte,这个大小只是保存堆中一个没有任 ...
随机推荐
- mysql用户权限管理
参考文章:http://www.cnblogs.com/jackruicao/p/6068821.html?utm_source=itdadao&utm_medium=referral (1) ...
- 后PMP时代下的敏捷项目管理全国在线讲座
活动时间:2017年9月7日(周四) 19:00-21:00 活动形式:在线直播 本次活动免费 互联网经济冲击下,产品创新成为企业生存的关键,"双模"成为很多企业必然的选择,传统 ...
- css 禁止长按保存功能
*{-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;} 或者指定某个元 ...
- C++中值传递、指针传递、引用传递的总结
C++中值传递.指针传递.引用传递的总结 指针传递和引用传递一般适用于:函数内部修改参数并且希望改动影响调用者.对比值传递,指针/引用传递可以将改变由形参"传给"实参(实际上就 ...
- JavaScript学习日志(五):DOM
一,基本定义 DOM是针对HTML和XML文档的API,根据W3C的HTML DOM标准,html文档中所以内容(无论是元素还是标签还是注释还是元素属性)都是节点. 二,Node类型:每一个节点都含有 ...
- NHibernate教程(18)--对象状态
本节内容 引入 对象状态 对象状态转换 结语 引入 在程序运行过程中使用对象的方式对数据库进行操作,这必然会产生一系列的持久化类的实例对象.这些对象可能是刚刚创建并准备存储的,也可能是从数据库中查询的 ...
- [转载]C header files matching your running
原文地址:C header files matching your running kernel were not found.作者:[Opser]小默 c header files matching ...
- [转载]Word直接发布新浪博客(以Word 2013为例)
原文地址:Word直接发布新浪博客(以Word 2013为例)作者:paulke2011 注意:这篇博客直接由Word 2013发出!这虽然也算是一个教程,但更多的是一个试验品. 老早就知道Word有 ...
- 大家一起来找茬(BUG)
大家一起来找茬(BUG) ----------目录---------- 一.上手体验 1.主界面 2.功能 二.程序的 BUG 三.必应词典的 BUG 1."每日一句"里的句子不能 ...
- 学号:201521123116 《java程序设计》第六周学习总结
1. 本章学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2.书面作业 1.1.Object对象中的clone方法是 ...