我到底需要多少内存(part 2) - 什么是shallow heap?

原创
2013/11/22 17:05
阅读数 1.4K

上一篇: 我到底需要多少内存(part 1) - 什么是retained heap? 

原文: 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大小的能力,你现在拥有终极力量去计算你的数据结构真正需要多少内存.

展开阅读全文
加载中

作者的其它热门文章

打赏
0
1 收藏
分享
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部