内存使用Integer []与int []:使用classmexer.jar进行分析

时间:2015-09-14 13:16:34

标签: java memory classmexer

尝试使用classmexer.jar参考类似Java memory usage分析Java数组中的内存使用情况(原始数据类型与对象)。

当我尝试使用代码时,我根本无法理解输出 (我在评论中给出了每个print语句的输出)

Integer[] intObjArray = new Integer[10];
System.out.println(MemoryUtil.memoryUsageOf(intObjArray)); // 56
System.out.println(MemoryUtil.deepMemoryUsageOf(intObjArray)); // 56
for (int j  =0; j< intObjArray.length ; j++) {
    intObjArray[j] =  new Integer(j);
}
System.out.println(MemoryUtil.memoryUsageOf(intObjArray)); //56
System.out.println(MemoryUtil.deepMemoryUsageOf(intObjArray)); //256


int[] intArray = new int[10];
System.out.println(MemoryUtil.memoryUsageOf(intArray)); //56
System.out.println(MemoryUtil.deepMemoryUsageOf(intArray)); //56
for (int j  =0; j< intArray.length ; j++) {
    intArray[j] =  10;
}
System.out.println(MemoryUtil.memoryUsageOf(intArray)); //56
System.out.println(MemoryUtil.deepMemoryUsageOf(intArray)); //56

2 个答案:

答案 0 :(得分:2)

我假设memoryUsageOf给出了数组使用的内存,而deepMemoryUsageOf给出了数组使用的内存+数组引用的对象使用的内存。

int[]的情况下,两者都返回相同的值,因为数组不引用任何对象。数组对象本身可能有16个字节的开销,每个int可能有4个字节(16 + 4 * 10 = 56)。

Integer[]的情况下,memoryUsageOf为数组返回16个字节,为10个引用中的每一个返回4个字节。

deepMemoryUsageOf返回16 + 4 * 10 +(16 + 4)* 10。 16+4是单个Integer实例占用的内存 - 我再次假设16个字节是任何对象的常量开销,int成员还需要4个字节。

答案 1 :(得分:1)

数组int[10]需要56个字节:

  • 数组对象的12个字节(普通对象为8个字节,长度值为4个字节)
  • 40 = 10个原始int值的10 * 4个字节
  • 4个字节,将大小填充为8的倍数(12 + 40 = 52,填充到56 = 8 * 7)

将数组元素设置为特定值不会更改内存大小。 浅而深的尺寸是一样的。

同样,数组Integer[10]本身需要56个字节:

  • 数组对象的12个字节
  • 40 = 10 * 4字节,用于10个对象引用
  • 4个字节,将大小填充为8的倍数

如果数组的所有元素都为null,那么深度大小等于浅的大小。

但是如果将数组元素设置为10个不同的Integer对象,那么10个Integer对象的内存将被添加到浅层大小:

一个整数对象需要16个字节:

  • 对象的8个字节
  • 内部int值的<4>字节
  • 4个字节用于填充

现在Integer[10]的深度为56 + 10 * 16 = 216字节。

似乎你的问题有一个拼写错误,它必须是216个字节而不是256个字节,至少在32位Hotspot JVM上。这是一个警告:如果您使用不同的JVM供应商,JVM版本和/或不同的处理器架构,所有这些内存数可能会有所不同。