转载自:http://blog.csdn.net/sodino/article/details/24186907
查看Mat文档时里面是这么描述Shallow Heap的:Shallow heap is the memory consumed by one object. An object needs 32 or 64 bits (depending on the OS architecture) per reference, 4 bytes per Integer, 8 bytes per Long, etc. Depending on the heap dump format, the size may be adjusted (e.g. aligned to 8, etc...) to model better the real consumption of the VM.
翻译过来: shallow heap是一个对象的内存消耗,依据os系统架构,一个对象可能需要4个字节或者8个字节。integer 类型消耗 4个字节, Long消耗 8个字节。由于heap dump的格式,分配的大小会比实际vm消耗的要大一些。
照这么说,在Android机子上,每个Object的Shallow Heap开销应该是8 bytes 再加上该对象每个内部成员变量的内存开销。
Class Demo0 {} Class Demo1 { int int_num = 0; }
以上面两个类为例,Demo0的对象Shallow Heap大小应该是8 bytes,那么Demo1的Shallow Heap大小应该是8 + 4 = 12 bytes。但MAT的结果却显示值为16 bytes,如下图:
Class Demo12 { int int_num = 0; int int_num1 = 0; } Class Demo13 { int int_num = 0; int int_num1 = 0; int int_num2 = 0; }
上面这两个类的对象中,Shallow Heap 对应的大小如图2所示分别为
Demo12 : 16 bytes;
Demo13: 24 bytes;
至此,就由不得猜想JVM在分配内存时是以8 bytes为粒度进行分配的了。
Google一下得文章:Java对象内存结构,英文版Java Objects Memory Structure。
由此猜想得到验证。
由于对象是以8 bytes为粒度进行分配的,所以Demo1仅仅用去一个4 bytes的int,仍空余着另外的4 bytes,这空余的4 bytes可以再声明第2个int成员变量变成Demo12。如果要再声明第3个int成员变量时,需要再另外分配出8 bytes的空间,即变为24bytes的Demo13了。
由此问题发现,VM为一个对象所分配的空间,并不一定是当前这个对象中成员变量所占内存的大小和,极可能是偏大的。
另附各种数据类型所需的字节数如下表。
类型 |
bytes |
long |
8 |
int |
4 |
short |
2 |
char |
2 |
boolean |
1 |
byte |
1 |
ref(引用) |
4 |