内存中java byte []的大小

时间:2015-08-30 03:03:52

标签: java memory-leaks byte

所以我创建了一个非常大的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或更多..有谁知道这里发生了什么?

感谢您阅读

2 个答案:

答案 0 :(得分:4)

所有对象都有维护对象的开销,“类型”又称Class等信息。请参阅What is the memory consumption of an object in Java?

数组也有length,并且64位Java中的开销可能更大。

由于您要分配50,000,000个16字节的数组,因此获得50_000_000 * (16 + overhead) + (overhead + 50_000_000 * pointerSize)。第二部分是数组的外部数组。

根据您的要求,您可以通过以下两种方式之一来改进:

  1. 将二维数组的索引翻转为byte[16][50_000_000]。这减少了50,000,001到17的开销,减少了外部阵列的大小。

  2. 使用单个数组byte[16 * 50_000_000]并自行进行偏移逻辑。这将使您的16个字节保持连续并消除所有开销。

答案 1 :(得分:1)

  

我可以看到大多数byte []都是24bytes而不是16

除了保存对象字段的空间之外,Java中的对象还有几个标题信息。在数组的情况下,还有一个单词来保存数组的length字段。 length实际上需要4个字节('cos lengthint),但JVM最有可能与您平台上的8字节边界对齐。

如果您看到占用24个字节的16字节数组,那么空间的计算很可能包括(仅)length字。

(请注意,对象/数组头占用的实际空间是JVM和特定于平台的。)

  

...我看到相当大的字节[]大小为472或更大。

那些是无关的。如果代码的其他部分没有显式创建它们,则很可能是由Java运行时库创建的。