4

I'm attempting to use Java Object Layout (JOL) to measure the instance size of an object that holds onto instances of some Java Records. I am getting an UnsupportedOperationException with a description "can't get field offset on a record class" when using GraphLayout.parseInstance. I get the same error when using ClassLayout.parseClass.

I was initially using Java 20, but have downgraded to Java 17. I tried the last two versions of JOL (0.17 and 0.16). I tried the recommendation from the stack trace "Cannot get the field offset, try with -Djol.magicFieldOffset=true". It looks like Records are not supported in HotspotUnsafe.fieldOffset and specifically at line 647 in Unsafe.

Here's an example of a class that passes and similar record that throws the exception.

public class Outer {
    public static void main(String[] args) {
        // Passes - outputs 72
        System.out.println(GraphLayout.parseInstance(new A(1, "one")).totalSize());

        // Fails with UnsupportedOperationException
        // "can't get field offset on a record class: private final int Outer$B.value"
        // sun.misc.Unsafe.objectFieldOffset - line 648
        System.out.println(GraphLayout.parseInstance(new B(1, "one")).totalSize());
    }

    public static class A {
        int value;
        String name;

        public A(int value, String name) {
            this.value = value;
            this.name = name;
        }
    }

    public static record B(int value, String name) {
    }
}

I did some searching to find examples of using JOL with Java Records but did not find anything. Is this possible with JOL currently, using some configuration settings I may have missed?

Donald Raab
  • 6,458
  • 2
  • 36
  • 44

2 Answers2

4

The answer is Yes, Java Object Layout does work with Java Records and requires the option -Djol.magicFieldOffset=true to be passed on the command line. According to Aleksey, this option was added specifically to work with records.

I was running the code from IntelliJ and was setting the option in program arguments text box instead of vmoptions text box (which I had to add first). Adding the option to vmoptions in Run/Debug Configurations fixed the issue.

Donald Raab
  • 6,458
  • 2
  • 36
  • 44
1

Gradle 7.4.1 with java 17/19 via intellij-plugin no problem with record-sizes. intellij-plugin with size

openjdk 19.0.2: Unsafe.java Unsafe.java with UOE for Record

SvenJu
  • 31
  • 1
  • 5