java对象数组大小
在计算对象数组的内存大小时,以下代码给出了预期的“已使用的24字节”,据我所知,这包括:java对象数组大小,java,arrays,object,Java,Arrays,Object,在计算对象数组的内存大小时,以下代码给出了预期的“已使用的24字节”,据我所知,这包括: 4字节(元素指针)+16字节(对象头)+4字节(元素空间)=24字节 // with JVM argument -XX:-UseTLAB public static void main(String[] args) { long size = memoryUsed(); Object[] o = new Object[]{1}; //Object[] o = new Object[]
4字节(元素指针)+16字节(对象头)+4字节(元素空间)=24字节
// with JVM argument -XX:-UseTLAB
public static void main(String[] args) {
long size = memoryUsed();
Object[] o = new Object[]{1};
//Object[] o = new Object[]{1L};
size = memoryUsed() - size;
System.out.printf("used %,d bytes%n", size);
//Output: used 24 bytes
}
public static long memoryUsed() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
但是,当元素类型更改为Long(1L)时,结果令人困惑,大多数情况下它是“使用了9264字节”,有人能帮我启发一下吗?这两种元素类型的内存分配有什么不同
// with JVM argument -XX:-UseTLAB
public static void main(String[] args) {
long size = memoryUsed();
//Object[] o = new Object[]{1};
Object[] o = new Object[]{1L};
size = memoryUsed() - size;
System.out.printf("used %,d bytes%n", size);
//Output: used 9,264 bytes
}
通常有一种更好的方法来计算对象大小,因为有一种专门的工具,称为 你的想法并不完全正确。该对象的总大小将为
40字节
。让我们看看这个空间是从哪里来的:
12 bytes headers (8 bytes + 4 bytes, since there are two headers)
您认为它是16字节
(8+8),但默认情况下有压缩oops
选项。您可以通过-XX:-UseCompressedOops
禁用它,实际上,在这种情况下,头的大小将为16字节
4 bytes size of the array (arrays have an int size that is stored in headers)
4 bytes is the reference size of the Integer (1)
4 bytes alignment (since objects are 8 bytes aligned - this is the trick behind CompressedOops btw)
到目前为止,阵列的24个字节
现在,在其中存储一个整数,这也是一个对象,因此:
12 bytes headers
4 bytes for the actual int value inside Integer
因此,总大小为40字节
可能要创建第二个数组,JVM必须加载额外的类(如Long
和它的内部类Long.LongCache
),这些类消耗的内存比您预期的要多。如果答案回答了您的问题,您可以在此接受答案。。。看看它是如何在这里完成的:可能是存储在这个数组中的整数是它的基元类型,所以它保存了额外的16bytes对象头吗@鄭无爲 您将它声明为对象
,因此它将是整数
;如果要保存该空间,需要将其声明为int[]