2015-08-30 14 views
1

所以我创建了一个非常大的byte []的数组,所以像字节[50,000,000] [16] ..所以根据我的数学这是800亿字节,这是0.8GB加上一些开销。 让我吃惊的是什么时候做在内存中的java字节[]的大小

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 []是24bytes不是16如预期,我看到[]尺寸472以上的不少大得多字节..有谁知道这里发生了什么?

感谢您阅读

+2

有一个数组'长度'字段。 –

回答

1

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

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

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

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


...我看到[]尺寸472以上的不少大得多字节。

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

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)。第二部分是数组的外部数组。

根据您的要求,你也许可以在以下两种方式之一来改善这样的:你有2维数组的

  1. 翻转的指数来byte[16][50_000_000]。这将开销从50,000,001降低到17,并减少了外部阵列的大小。使用单个数组byte[16 * 50_000_000]并自己做偏移逻辑。这将保持您的16个字节连续并消除所有开销。

+0

酷奇妙的建议 – darthShana

+0

@darthShana如果这个答案对你有好处,请点击勾号接受它,以便其他人可以看到它。 – Andreas

相关问题