我已经完成了一些阅读,但我对一件事情并不完全确定,例如在JVM 64位中会使用多少内存(对不起,如果有愚蠢的问题,但我有点困惑)并且对此不太了解):
MyObject [] myArray; - 我知道一个数组需要24个字节,但这个数组中的每个元素占用多少?每个元素都是一个对象引用,意味着每个元素8个字节?如果没有,我怎么知道这个数组中每个元素需要多少字节?
答案 0 :(得分:1)
通常,当使用小于32 GB的堆大小时,64位JVM使用compressed oops将对象指针存储为32位整数(使用时按三位缩放,因为所有对象都是对齐到8个字节;有关详细信息,请参阅链接),因此每个元素实际上只使用4个字节。
但是,如果使用超过32 GB的堆或以其他方式关闭压缩的oops,那么每个元素确实会使用8个字节。
另外,我怀疑你在数组头上的语句是24个字节是错误的。首先,在压缩oops时,标头中的类引用也会被压缩,而identity-hash-code和array length字段的开头是32位,所以我怀疑它更可能使用12个字节。即使使用全长oops,它仍然只需要16个字节。但是,我找不到任何硬源验证。但是,一般来说,应该说Hotspot甚至不使用固定大小的对象头,而是根据对象的各种情况改变大小。 This article描述了其中一些情况。
至少在Hotspot JVM上。由于JLS没有指定任何原始大小,理论上它 可以是任何给定JVM上的任何东西,尽管8个字节当然是最可能的实现选择。
答案 1 :(得分:0)
Here是关于如何计算Java数组的内存使用情况的很好的信息
例如
让我们考虑一个10x10的int数组。首先,"外部"数组有12个字节的对象标题,后跟10个元素的空格。这些元素是构成行的10个数组的对象引用。那就是12 + 4 * 10 = 52个字节,然后必须向上舍入到8的下一个倍数,得到56.然后,10行中的每一行都有自己的12字节对象头,4 * 10 = 40字节对于实际的整行行,再次使用4个字节的填充,使该行的总数达到8的倍数。因此总共得到11 * 56 = 616个字节。这比你只计算10 * 10 * 4 = 400字节的百分之一还要大一些" raw"自己。