Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object header size in Java on 64bit VM with <4GB RAM

I wanted to know if there is some way to have the 64bit VM use 8byte object headers instead of 12byte object headers if the usable RAM for the JVM is 4GB anyway.

Or is it like that on Linux, if not on windows? Could someone test this with this code?

import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class ObjectSizes {
    String s1;
    String s2;
    public static void main(String[] args) throws Exception {
        Unsafe unsafe;
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe)field.get(null);
        } catch (Exception ex) {
            throw new RuntimeException("Can't get Unsafe instance.", ex);
        }
        Field s1Field = ObjectSizes.class.getDeclaredField("s1");
        Field s2Field = ObjectSizes.class.getDeclaredField("s2");
        long s1OffSet = unsafe.objectFieldOffset(s1Field);
        long s2OffSet = unsafe.objectFieldOffset(s2Field);
        System.out.println("We are running "+System.getProperty("java.version"));
        System.out.println("Object header size is "+s1OffSet+" bytes.");
        System.out.println("Object reference size is "+(s2OffSet-s1OffSet)+" bytes.");
    }
}
like image 969
Daniel Avatar asked Jun 27 '13 06:06

Daniel


People also ask

What is size of object 64 bit system?

2.1. Minimum object size is 16 bytes for modern 64-bit JDK since the object has 12-byte header, padded to a multiple of 8 bytes.

How much memory does a Java object use?

Object references consume 4 bytes. boolean and byte values consume 1 byte. short and char values consume 2 bytes. int and float values consume 4 bytes.

How do you find the size of an object in Java?

Unlike languages such as C/ C++ which has a function sizeof() to get memory size of any object, Java has no such direct method. It is, still, possible to get the size of an object in Java using its instrumentation package. Instrumentation package in Java is used to instrument any Java code and get details of it.


2 Answers

It doesn't look like it's possible to have an 8-byte object header on a 64-bit JVM. The header consists of a "mark word", a pointer to the object's class, array size in case of an array, and padding to reach the next 8-byte boundary.

  ,------------------+------------------+------------------ +---------------.
  |    mark word     |   klass pointer  |  array size (opt) |    padding    |
  `------------------+------------------+-------------------+---------------'
  • The mark word may be used to store native pointers to implement locks and to help GC, so it occupies 8 bytes on a 64-bit JVM.
  • With heaps smaller than 32GB the pointer to the object's class is compressed to 4 bytes.
  • The padding may be used to store one of the fields.

Therefore the object header on a 64-bit system can occupy as little as 8 + 4 = 12 bytes, but not less.

like image 72
Joni Avatar answered Nov 14 '22 01:11

Joni


For 64 bit VMs there are options:

  1. Using compressed pointers via -XX:+UseCompressedOops (enabled by default on Java 6)

In that case: object headers will be 12 bytes, array headers will be 16 bytes (last 4 byte for size of array)

2.Not using compressed pointers via -XX:-UseCompressedOops

In that case: object headers will be 16 bytes, array headers will be 20 bytes (last 4 byte for size of array)

The code given above is not VM bit-size independent and will give different results for 32-bit and 64-bit vms. You need to consider bit-ness and compressed oops factors to compute correct size.

like image 36
NitinS Avatar answered Nov 14 '22 01:11

NitinS