Thursday, December 18, 2025

Measuring Java Object Size with JOL (Java Object Layout)

JOL (Java Object Layout) is a small but powerful tool developed by the OpenJDK team that lets you inspect and measure how Java objects are actually laid out in memory.

With JOL, you can:

  • Inspect object headers and field offsets
  • See padding and alignment effects
  • Measure shallow and deep object sizes
  • Compare layouts across JVM configurations

Let's start with the following simple class:

public class Point {
  int x;
  int y;
}

Now use JOL to inspect its layout using ClassLayout:

import org.openjdk.jol.info.ClassLayout;

public class JolExample {
  public static void main(String[] args) {
    System.out.println(ClassLayout.parseClass(Point.class).toPrintable());
  }
}

The output is:

Point object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE
  0   8        (object header: mark)     N/A
  8   4        (object header: class)    N/A
 12   4    int Point.x                   N/A
 16   4    int Point.y                   N/A
 20   4        (object alignment gap)    
Instance size: 24 bytes

This shows that even though the Point class only has 2 int fields requiring a total of 8 bytes, the actual object uses three times that amount (24 bytes), due to the object header (12 bytes) and alignment (4 bytes).

Shallow Size vs. Deep Size

The shallow size is the memory consumed by the object itself, excluding objects it references i.e. it includes the fields, object header and padding, but not referenced objects.

The deep size, on the other hand, includes the entire object graph reachable from the object.

To demonstrate this, let's look at the following example:

public class Address {
  private final String city;

  public Address(String city) {
    this.city = city;
  }
}

public class Person {
  private final String name;
  private final Address address;
  private final int age;

  public Person(String name, Address address, int age) {
    this.name = name;
    this.address = address;
    this.age = age;
  }
}

Here is the JOL output, which shows the shallow size of the Address and Person:

> ClassLayout.parseClass(Address.class).toPrintable();

Address object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     N/A
  8   4                    (object header: class)    N/A
 12   4   java.lang.String Address.city              N/A
Instance size: 16 bytes

> ClassLayout.parseClass(Person.class).toPrintable();

Person object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     N/A
  8   4                    (object header: class)    N/A
 12   4                int Person.age                N/A
 16   4   java.lang.String Person.name               N/A
 20   4            Address Person.address            N/A
Instance size: 24 bytes

As shown above, the Person's shallow size includes the object header, age and object references (name and address), but does not include the String object for name, Address object, String inside Address, or any backing char[] or byte[] arrays.

To see the deep size of the Person, use GraphLayout instead of ClassLayout, like this:

import org.openjdk.jol.info.GraphLayout;

public class JolExample {
  public static void main(String[] args) {
    final Address address = new Address("London");
    final Person person = new Person("Alice", address, 30);
    System.out.println(GraphLayout.parseInstance(person).toFootprint());        
  }
}

The output is:

Person@27abe2cdd footprint:
     COUNT       AVG       SUM   DESCRIPTION
         2        24        48   [B
         1        16        16   Address
         1        24        24   Person
         2        24        48   java.lang.String
         6                 136   (total)

That's 136 bytes in total. Note that each String is backed by a byte array (represented by [B) which is 24 bytes.

Therefore, Person is only 24 bytes shallow, but costs 136 bytes deep.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.