内存中 java byte[] 的大小
size of java byte[] in memory
所以我创建了一个非常大的 byte[] 数组,比如 byte[50,000,000][16].. 所以根据我的数学计算,这是 800,000,000 字节,即 0.8GB 加上一些开销。
令我惊讶的是什么时候做
memoryBefore = runtime.totalMemory() - runtime.freeMemory()
它使用 1.8GB 内存。当我将分析器指向它时,我得到了这个
https://www.dropbox.com/s/el9vlav5ylg781z/Screen%20Shot%202015-08-30%20at%202.55.00%20pm.png?dl=0
我可以看到大多数 byte[] 是 24 字节,而不是预期的 16 字节,而且我看到很多更大的字节 [],大小为 472 或更大。有人知道这里发生了什么吗?
感谢阅读
I can see most byte[] are 24bytes not 16
Java 中的 object 除了包含 object 的字段的 space 之外,还有几个词的 header 信息.在数组的情况下,还有一个额外的词来保存数组的 length
字段。 length
实际上需要 4 个字节('cos length
是一个 int
),但 JVM 很可能与您平台上的 8 字节边界对齐。
如果您看到 16 字节数组占用 24 个字节,那么 space 的计算很可能包括(仅)length
字。
(请注意,object/数组 headers 实际占用的 space 是特定于 JVM 和平台的。)
... I see quite a few much larger byte[] of size 472 or more.
那些是无关的。如果您的代码的某些其他部分未明确创建它们,则它们很可能是由 Java 运行时库创建的。
所有对象都有维护对象的开销,如 "type" 又名 Class
的信息。参见 What is the memory consumption of an object in Java?。
数组也有一个 length
,开销 可能 在 64 位 Java 中更大 Java。
由于您分配了 50,000,000 个 16 字节的数组,因此您得到 50_000_000 * (16 + overhead) + (overhead + 50_000_000 * pointerSize)
。第二部分是数组的外层数组。
根据您的要求,您可以通过以下两种方式之一改进此功能:
将二维数组的索引翻转为byte[16][50_000_000]
。这将开销从 50,000,001 减少到 17,并减少了外部数组大小。
使用单个数组byte[16 * 50_000_000]
并自己做偏移逻辑。这将使您的 16 个字节保持连续并消除所有开销。
所以我创建了一个非常大的 byte[] 数组,比如 byte[50,000,000][16].. 所以根据我的数学计算,这是 800,000,000 字节,即 0.8GB 加上一些开销。 令我惊讶的是什么时候做
memoryBefore = runtime.totalMemory() - runtime.freeMemory()
它使用 1.8GB 内存。当我将分析器指向它时,我得到了这个
https://www.dropbox.com/s/el9vlav5ylg781z/Screen%20Shot%202015-08-30%20at%202.55.00%20pm.png?dl=0
我可以看到大多数 byte[] 是 24 字节,而不是预期的 16 字节,而且我看到很多更大的字节 [],大小为 472 或更大。有人知道这里发生了什么吗?
感谢阅读
I can see most byte[] are 24bytes not 16
Java 中的 object 除了包含 object 的字段的 space 之外,还有几个词的 header 信息.在数组的情况下,还有一个额外的词来保存数组的 length
字段。 length
实际上需要 4 个字节('cos length
是一个 int
),但 JVM 很可能与您平台上的 8 字节边界对齐。
如果您看到 16 字节数组占用 24 个字节,那么 space 的计算很可能包括(仅)length
字。
(请注意,object/数组 headers 实际占用的 space 是特定于 JVM 和平台的。)
... I see quite a few much larger byte[] of size 472 or more.
那些是无关的。如果您的代码的某些其他部分未明确创建它们,则它们很可能是由 Java 运行时库创建的。
所有对象都有维护对象的开销,如 "type" 又名 Class
的信息。参见 What is the memory consumption of an object in Java?。
数组也有一个 length
,开销 可能 在 64 位 Java 中更大 Java。
由于您分配了 50,000,000 个 16 字节的数组,因此您得到 50_000_000 * (16 + overhead) + (overhead + 50_000_000 * pointerSize)
。第二部分是数组的外层数组。
根据您的要求,您可以通过以下两种方式之一改进此功能:
将二维数组的索引翻转为
byte[16][50_000_000]
。这将开销从 50,000,001 减少到 17,并减少了外部数组大小。使用单个数组
byte[16 * 50_000_000]
并自己做偏移逻辑。这将使您的 16 个字节保持连续并消除所有开销。