2

Tried analysing memory usage of in Java Arrays (primitive data type versus Objects) using classmexer.jar with reference to the like Java memory usage.

When I tried following code I am not able to understand the output at all (I have given output of each print statement in comments)

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
assylias
  • 321,522
  • 82
  • 660
  • 783
Dhruv
  • 10,291
  • 18
  • 77
  • 126

2 Answers2

2

I'm assuming memoryUsageOf gives the memory used by the array while deepMemoryUsageOf gives the memory used by the array + the memory used by the objects referred by the array.

In the case of int[] both return the same value, since the array refers to no objects. There's probably a 16 bytes overhead for the array object itself + 4 bytes for each int (16 + 4 * 10 = 56).

In the case of Integer[], memoryUsageOf returns 16 bytes for the array + 4 bytes for each of the 10 references.

deepMemoryUsageOf returns 16 + 4*10 + (16+4)*10. 16+4 is the memory taken by a single Integer instance - again I'm assuming the 16 bytes is a constant overhead for any object, and additional 4 bytes are taken by the int member.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • where we got 16 bytes for array. http://www.javamex.com/tutorials/memory/object_memory_usage.shtml link says it should be 12 for array and 8 for normal object.. Sorry may be i am confused.. – Dhruv Sep 14 '15 at 14:23
1

The array int[10] needs 56 bytes:

  • 12 bytes for the array object (8 bytes for the ordinary object + 4 bytes for the length value)
  • 40 = 10 * 4 bytes for 10 primitive int values
  • 4 bytes to pad the size to a multiple of 8 (12 + 40 = 52, padding to 56 = 8*7)

Setting the array elements to specific values does not changed the memory size. Shallow and deep size are the same.


Likewise the array Integer[10] itself needs 56 bytes:

  • 12 bytes for the array object
  • 40 = 10 * 4 bytes for 10 object references
  • 4 bytes to pad the size to a multiple of 8

If all elements of the array are null, then the deep size equals the shallow size.

But if you set the array elements to 10 different Integer objects, then the memory of the 10 Integer objects are added to the shallow size:

One Integer object needs 16 bytes:

  • 8 bytes for the object
  • 4 bytes for the internal int value
  • 4 bytes for padding

Now the deep size of the Integer[10] is 56 + 10 * 16 = 216 bytes.

Seems you got a typo in your question, it must be 216 bytes and not 256 bytes, at least on a 32-bit Hotspot JVM. That's the caveat: All these memory numbers might differ if you use a different JVM vendor, JVM version and/or different processor architecture.

wero
  • 32,544
  • 3
  • 59
  • 84