我到底需要多少内存(part 1)

徘徊边缘 提交于 2020-03-08 18:49:40

原文: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的.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!