原文:http://plumbr.eu/blog/how-much-memory-what-is-retained-heap

我将需要多少内存?当你构建一个解决方案,创建一个数据结构或者选择一个算法时这个问题你可能问过自己或者别人.请问这个图是否适合在我的3G堆上,它包含1,000,000条边并且我使用HashMap存储它?我可以使用标准的集合API来构建我的自定义缓存解决方案或者他们带来的开销太大?

显然,回答这个简单的问题有点复杂.在这篇文章中我们将一窥全豹看这个坑到底有多深.

回答标题中的问题来自于几个部分.首先我们需要了解你是否对shallow heap和retained head的大小有兴趣.
shallow heap比较容易 - 它仅仅是自己本身所占有的堆内存.如果计算它有一些细微差别,但是不在本文的范围内.敬请期待未来相同主题的文章.

retained heap有许多计算方式更有趣.你不会对shallow heap感兴趣,在大多数情况下你的问题又可以说成"如果从内存中移除这个对象,通过垃圾回收会有多少内存被释放".

现在,我们都还记得,所有的Java垃圾回收算法都是以下的逻辑:
1. 有一些对象被GC认为是"重要的".被叫做GC root并且几乎不会被回收.比如,当前运行方法的本地变量和输入参数,程序线程,来自本地代码的引用和类似于"全局"的对象.
2. 任何从GC root引用的对象都被假定为在使用所以不会被GC回收.在Java里一个对象可以通过不同的方式引用其他对象,大多数常规情况是一个对象A被存储为对象B的一个字段.这种情况我们叫做"B引用A".
3. 能从GC root到达的所有对象被标记为"in use"的这个过程一直在重复.
4. 所有未使用的对象都可以被回收.

现在说明如何计算retained heap,让我们按照上述的算法看下接下来的示例对象:

简化下这个例子,我们估算所有的对象O1-O4的shallow heap是1kB.我们开始计算对象的retained heap的大小.
1. O4没有引用其他的对象,所以他的retained heap和他的shallow heap的大小相同是1kB.
2. O3有一个到O4的引用.垃圾回收O3意味着O4适合于垃圾回收的也会被回收所以我们说O3的retained heap是2kB.
3. O2有一个到O3的引用.但是现在需要着重注意的是移除O2指向O3的指针也不会使O3可以被垃圾回收,因为O1仍然对他有一个指针.所以O2的retained heap的大小仅仅是1kB.
4. 在这个图上O1保持着所有的引用,因为如果我们移除O1,这个图上的所有对象会被垃圾回收.所以O1的retained heap是4kB.

在实际练习中是哪种含义?实事上,了解shallow heap和retained heap大小的不同可以用工具去做这个工作就像memory探查和heap dump分析 - 比如如果你不了解如何区分这两种heap的大小会证明不可能去钻研Eclipse MAT的.

原文: http://plumbr.eu/blog/how-much-memory-do-i-need-part-2-what-is-shallow-heap

一个特定的数据结构的大小是多少?
"我可以把所有这些对象放到我的ehCache中吗?"

这篇文章是我们试着回答那些问题系列的第二篇.上一篇文章解释了一个对象的retained heap和shallow heap的不同.在文章中我们也提供了一个例子如何去计算一个数据结构的retained heap.在今天的这篇文章中我们将扩展我们在前面称为"simple"的问题. 换句话说 - 如何去估算一个对象的shallow heap.

在第一篇文章中我们推开一大堆复杂性说明计算shallow heap的大小是很容易的 - 它只包含对象本身占用的堆.但是如何计算这个对象"它自己"需要多少堆内存?显示有一个工式:

Shallow Heap的大小 = [类的引用] + 父类字段的大小 + 实例字体的大小 + [对齐]

似乎没有太大的帮助,是吧?我们使用下面的示例代码去尝试工作:

class X {    int a;    byte b;    java.lang.Integer c = new java.lang.Integer();
}class Y extends X {java.util.List d;    java.util.Date e;
}

现在,我们努力回答一下这个问题 - 一个Y实例需要多少shallow heap?我们开始计算它,假定我们在一个32位的系统架构上:

开始 - Y是X的子类,所以它的大小包含了来自父类的"某些东西".因此,在计算Y大小的之前,我们先计算X的shallow heap的大小.

转入关于X的计算,前8个字节被用作类的引用.这个引用在所有的Java对象中一直存在是被JVM用来定义后续状态的内存布局.它有三个实例变量 - 1个int,1个Integer和1个byte.这些实例变量需要的堆如下:

1. byte应该是什么.在内存是就是1个字节. 
2. int在32位架构中需要4个字节. 
3. Integer的引用也需要4个字节.注意当计算retained heap的时候,我们也会考虑包装到Integer对象中的原始类型的大小,但是我们在这计算shallow heap的大小,我们只需要4个字节的引用.

所以 - 是这样吗?X的shallow heap是类的引用8个字节 + 1个字节(byte) + 4个字节(int) + 4个字节(Integer的引用) = 17个字节?实事上 - 不对.现在被称为对齐的(也叫补齐)开始发挥作用了. 意思是JVM分配内存是8字节的倍数,所以我们创建一个X实例是分配24个字节而不是17个字节.

如果你可以跟着我们一直到这,很好,不过现在我们要试着做一些更加复杂的.我们不是创建X实例,而是创建Y实例.意思是 - 我们可以减掉8个字节的类引用和补齐的值.这个可能不太明显但是 - 你是否有注意到当计算X的shallow heap大小的时候我们没有考虑所有的类都是继承了java.lang.Object如果你没有在你的代码中显式的说明.我们没有考虑父类的header,因为JVM足够聪明去检查来类自己的定义,而不是去复制到对象的header.

这同样适用于补齐 - 当创建一个对象你只要补齐一次,而不是在父类/子类的边界.所以我们可以说当创建一个X子类你将只继承到来自实例变量的9个字节.

最后我们回到最初的任务开始计算Y的大小.正好我们看到的,我们已经丢失了父类的9个字节.让我们看一下当我们真实的构造一个Y的实例将会增加些什么.

1. Y的header参见它的类定义占用的8个字节.和前面的一个相同. 
2. Date是一个对象的引用.4个字节.简单. 
3. List是一个容器的引用.也是4个字节.无关紧要.

所以除了来自父类的9个字节我们还有来自header的8个字节,来自两个引用(List和Date)的2*4个字节.Y实例的总的shallow heap的大小会是25个字节,补齐到32个字节.

要使计算容易点,我们已经汇总如下图:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
  Align Align Align Align
X Object a b c  
Y Object a b c d e  

有了这些知识你可以做什么?连同计算retained heap大小的能力,你现在拥有终极力量去计算你的数据结构真正需要多少内存.

retained heap shallow heap 区别及介绍相关推荐

  1. MAT工具学习,incoming reference和outgoing reference,Shallow Heap和Retained Heap

    MAT工具学习 incoming reference和outgoing reference Shallow Heap和Retained Heap 常用工具 一般思路 incoming referenc ...

  2. Eclipse MAT 里面的SHALLOW HEAP和RETAINED HEAP是什么意思?

    原文在这里: Eclipse MAT 里面的SHALLOW HEAP和RETAINED HEAP是什么意思? MAT是一款非常强大的JVM内存映像分析工具,对分析内存相关的问题非常有用,MAT报告中对 ...

  3. Memory Analyzer Tool 1 Shallow heap Retained heap dominator tree(控制树)

    文章目录 1. shallow heap 2. retained heap 3. dominator tree(控制树) 1. shallow heap 引用原文介绍 :Shallow heap is ...

  4. b360装服务器系统,B365主板能不能安装Win7系统 B365和B360主板区别对比介绍

    前不久,Intel低调放出了B365芯片组主板,预计将于2月底发布.从名称来看,B365主板似乎是B360的升级版,网传其可能原生支持Win7系统,受到不少电脑爱好者朋友关注.那么B365主板能不能安 ...

  5. HEAP: Free Heap block XXXX modified at XXXX after it was freed

    开发过程中,有时候会遇到堆异常的情况 这时,VS的调试输出窗口会提示: HEAP[MemTest.exe]: HEAP: Free Heap block 39b998 modified at 39b9 ...

  6. php div行内块元素,行内元素与块级元素的区别详细介绍

    首先,CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,分别为块级(block).行内(inline). 块级元素:(以下列举比较常用的块级元素,详 ...

  7. HEAP: Free Heap block xxxxxxxx modified at xxxxxxxx after it was freed

    <诸子百家>发布后,发现游戏在有些情况下会崩溃.偶然崩溃. 由于我是负责主框架,网络协议和登录,数据等,所以这个修正bug的任务主要就落在我头上了. 一.bug 1.最头疼的bug HEA ...

  8. mx250是什么_MX250和150有什么区别 MX250和MX150区别对比介绍

    NVIDIA早在17年的时候,推出了MX150显卡,主要用于高性能轻薄本,兼顾续航与一般的游戏性能,在低画质下可以勉强吃鸡.时隔两年,新一代MX250显卡正式发布,同样是定位"高性能轻薄本& ...

  9. 颜色之ARGB与RGB、RGBA的区别与介绍

    ARGB 是一种色彩模式,也就是RGB色彩模式附加上Alpha(透明度)通道,常见于32位位图的存储结构. RGB 色彩模式是工业界的一种颜色标准,是通过对红(R).绿(G).蓝(B)三个颜色通道的变 ...

  10. Docker和k8s的区别与介绍

    Docker和k8s的区别与介绍 https://www.cnblogs.com/misswangxing/p/10669444.html Docker技术的三大核心概念,分别是: 镜像(Image) ...

最新文章

  1. MySQL:left join 避坑指南
  2. 网站服务器蜘蛛日志怎么看,如何查看百度蜘蛛,google蜘蛛爬取记录?《网站日志分析篇》...
  3. python 处理xml pandas_Python数据处理分析,解决pandas中所有的Excel疑难杂症(上)
  4. hook什么意思_这是什么骚代码!
  5. 运河杯交通违章 运行不起来
  6. vue 双数据绑定原理
  7. 【调用IP宏文件进行仿真】modelsim仿真时出现 Instantiation of 'xxx' failed. The design unit was not found....
  8. 【jmeter】Include Controller控件Test Fragment的使用
  9. 【PL/SQL】学习笔记 (1)一个简单的PL/SQL程序
  10. Python机器学习:PCA与梯度上升:007试手MNIST数据集
  11. java从端口接收数据_java - Java中通过串行端口接收数据的效率更高 - 堆栈内存溢出...
  12. Android之Toolbar的三个问题:修改左边箭头颜色、怎样修改右边以及子activity中的toolbar添加返回箭头...
  13. Keil5新建工程小白指南
  14. 测试三极管的口诀[转]
  15. Tesseract综述
  16. android手机如何访问电脑tomcat服务器
  17. 高博视觉SLAM十四讲--罗德里格斯公式推导
  18. 京东2018年校园招聘笔试代码环节答案分享
  19. 计算机为什么有网络凭证,Win10访问局域网中计算机共享文件显示需要网络凭证怎么办?...
  20. 分布式计算,大型网站技术架构:核心原理与案例分析

热门文章

  1. Don't let the things you own end up owing you
  2. python爬去新浪微博_GitHub - dataabc/weiboSpider: 新浪微博爬虫,用python爬取新浪微博数据...
  3. ts的.d.ts和declare究竟是干嘛用的
  4. 普适计算-2014/03/21
  5. nginx根据post请求体内容转发
  6. Android—传感器-方向传感器
  7. 计算ndvi值需要的数据_MODIS计算NDVI注意事项
  8. 【折腾电脑】Edge浏览器看B站视频卡顿最全解决办法合集
  9. vue 嵌套表格组件_vue+element-ui实现嵌套表格导出
  10. ArcGis-制图(简单点、线、面符号的制作、保存)