Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java object array size

When calculate memory size of an object array, following code gives "used 24 bytes" as expected, which, as far as I know, consists of:

4bytes(element pointer)+16bytes(object header)+4bytes(element space) = 24bytes

// 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();
}

But when element type changed to Long (1L), the result is confusing, most of the time it's "used 9,264 bytes", anyone can help enlighten me? what is the difference in memory allocation between this two element type?

// 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
}
like image 264
鄭无爲 Avatar asked Nov 07 '22 13:11

鄭无爲


1 Answers

There is a better way to calculate an object size in general, as there is a specialized tool for that, called JOL.

It's not entirely correct how you think about it. The total size of that object is going to be 40 bytes. Let's see where this space is coming from:

12 bytes headers (8 bytes + 4 bytes, since there are two headers)

You thought it's 16 bytes ( 8 + 8 ), but there is the compressed oops option that is on by default. You can disable it via -XX:-UseCompressedOops and indeed in this case the size of the headers is going to be 16 bytes.

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)

So far you have 24 bytes for the array.

Now, you store an Integer inside it, that is an Object too, thus:

12 bytes headers
4 bytes for the actual int value inside Integer

Thus the total size is 40 bytes.

like image 157
Eugene Avatar answered Nov 15 '22 05:11

Eugene