最近看到网上很多文章讲如何计算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的更多相关文章

  1. Shallow Size 和 Retained Size

    所有包含Heap Profling功能的工具(MAT, Yourkit, JProfiler, TPTP等)都会使用到两个名词,一个是Shallow Size,另一个是 Retained Size. ...

  2. Java对象大小计算

    这篇说说如何计算Java对象大小的方法.之前在聊聊高并发(四)Java对象的表示模型和运行时内存表示 这篇中已经说了Java对象的内存表示模型是Oop-Klass模型. 普通对象的结构如下,按64位机 ...

  3. 两种计算Java对象大小的方法

    之前想研究一下unsafe类,碰巧在网上看到了这篇文章,觉得写得很好,就转载过来.原文出处是: http://blog.csdn.net/iter_zc/article/details/4182271 ...

  4. Java虚拟机14:Java对象大小、对象内存布局及锁状态变化

    一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...

  5. Java虚拟机18:Java对象大小、对象内存布局及锁状态变化

    一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...

  6. java调优随记-java对象大小

    在java中,基本数据类型的大小是固定.但是java对象的大小是不固定的,需要通过计算. 在java中,一个空对象(没有属性和方法的对象)在堆中占用8byte,比如 Object obj = new ...

  7. java对象大小

    Java对象的内存布局:对象头(Header),实例数据(Instance Data)和对齐填充(Padding) 对象头在32位系统上占用8B,64位系统上占16B. 无论是32位系统还是64位系统 ...

  8. GC之二--GC是如何回收时的判断依据、shallow(浅) size、retained(保留) size、Deep(深)size

    回到问题“为何会内存溢出?”. 要回答这个问题又要引出另外一个话题,既什么样的对象GC才会回收? 一.对象存活方式判断方法 在上一篇文章<GC之一--GC 的算法分析.垃圾收集器.内存分配策略介 ...

  9. jvm详情——2、Java对象在jvm中的大小

    Java对象的大小 基本数据的类型的大小是固定的,这里就不多说了.对于非基本类型的Java对象,其大小就值得商榷.在Java中,一个空Object对象的大小是8byte,这个大小只是保存堆中一个没有任 ...

随机推荐

  1. View.post() 不靠谱的地方你知道吗?

    版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有. 每周会统一更新到这里,如果喜欢,可关注公众号获取最新文章. 未经允许,不得转载. 一.前言 有时候,我们会需要 ...

  2. org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML.问题思路

    15:36:34,549 WARN DefaultListableBeanFactory:1416 - Bean creation exception on FactoryBean type chec ...

  3. linux(十)配置ssh免密登录实现

    知道ssh的朋友应该知道它是用来干什么的,如果你不知道什么是ssh远程登录的话,可以去看一下我的上一篇博客,关于linux的网络基础的知识.备注:ssh是用于远端登入.执行ssh指令开启终端机阶段作业 ...

  4. redi安装

    借鉴文章:https://segmentfault.com/a/1190000010709337 在linux中使用wget时,若报-bash: wget: command not found,则表明 ...

  5. Spring配置文件的xsd知识点

    今天在Spring配置文件中配置如下事务属性时,提示<tx is not bound(不受约束的),估计是配置文件的xsd没配置好. <!-- 2.配置事务属性 --> <tx ...

  6. Python教程百度网盘哪里有?

    Python为我们提供了非常完善的基础代码库,覆盖了网络.文件.GUI.数据库.文本等大量内容,被形象地称作"内置电池(batteries included)".带你快速入门的Py ...

  7. 针对通达OA20170729集团版设计门户管理解决方案的具体实例

    随着企业信息化建设的深入,应用系统数量不断增加,应用功能不断丰富,数据信息也在呈几何级数增长,在支撑企业正常工作运转的同时,也衍生出许多新的问题: 通达信科根据自身从业多年的行业实践经验,勇于打破传统 ...

  8. Web.py 框架学习笔记 - ctx

    摘要: ctx用于存取web请求的环境变量,基于ThreadedDict类进行实例化.ThreadedDict类可实例化字典类型的对象,该对象某些属性可用于存取处理线程的id. 这样字典化实例的线程池 ...

  9. httpd常用配置

    author:JevonWei 版权声明:原创作品 检查配置文件时,如下提示,则因为没有server的服务名称导致,故设置网站的服务server名称,若没有设置web服务名,主默认解析系统主机名(添加 ...

  10. css常用文本属性

    [CSS常用文本属性] 1. 字体.字号类: ① font-weight: 字体粗细. bold-加粗.normal-正常.lighter-细体 也可以使用100-900数值,400表示normal, ...