繁体   English   中英

内存中java字节[]的大小

[英]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

我可以看到大多数字节 [] 是 24 字节而不是预期的 16 字节,并且我看到了很多更大的字节 [] 大小为 472 或更多.. 有谁知道这里发生了什么?

谢谢阅读

所有对象都有维护对象的开销,例如“类型”即Class 请参阅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 个字节保持连续并消除所有开销。

我可以看到大多数字节 [] 是 24 字节而不是 16

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

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

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


...我看到了相当多的大小为 472 或更大的 byte[]。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM