最近看到网上很多文章讲如何计算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. 安全终端模拟工具Xshell 5使用密钥认证登录配置详细教程

    ▲版权声明:本文为博主原创文章,未经博主允许不得转载. Xshell支持SSH1 / SSH2协议,密码和DSA / RSA公钥用户认证方式等各种安全功能,并对各种加密算法进行加密.使用内置的Xshe ...

  2. php 微信公众号+微商城开发 基于Thinkphp3.2框架开发

    说明:本教程是自己自学+自己的理解+扩展(包括学习过程中遇到的一些问题) 参考教程:麦子学院--李忠益--http://www.maiziedu.com/u/70409/ 微盟: http://www ...

  3. zetcode :: First programs in PyQt5

    练习代码,详见网站 http://zetcode.com/gui/pyqt5/firstprograms/ import sys from PyQt5 import QtWidgets from Py ...

  4. Connector

    增加project bar窗口,在编辑大规模工程电路时,方便管理电路的各个层次,在分页编辑大规模工程电路时,可以用place中的off-page connector 进行每一页的联接.

  5. Jquery Mobile笔记之一

    jQuery Mobile 在你的网页中添加 jQuery Mobile 你可以通过以下几种方式将jQuery Mobile添加到你的网页中: 从 CDN 中加载 jQuery Mobile (推荐) ...

  6. 推荐一款接口文档在线管理系统-MinDoc

    项目简介 MinDoc 是一款针对IT团队开发的简单好用的文档管理系统. MinDoc 的前身是 SmartWiki 文档系统.SmartWiki 是基于 PHP 框架 laravel 开发的一款文档 ...

  7. SpirngMVC入门第一天

                                         SpringMVC第一天 1.   计划 第一天 1.SpringMVC介绍 2.入门程序 3.SpringMVC架构讲解 a ...

  8. 多模字符串匹配算法之AC自动机—原理与实现

    简介: 本文是博主自身对AC自动机的原理的一些理解和看法,主要以举例的方式讲解,同时又配以相应的图片.代码实现部分也予以明确的注释,希望给大家不一样的感受.AC自动机主要用于多模式字符串的匹配,本质上 ...

  9. Java 反射之动态代理

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt205 利用Java反射机制你可以在运行期动态的创建接口的实现.java.la ...

  10. makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解

    在linux中输入vi Makefile 来实现创建Makefile文件 注意:命令行前必须加TAB键 例如:将两个文件led.c和crt0.S汇编文件,制作一个Makefile文件 led.bin ...