我正在try 使用Java Object Layout(JOL)来测量持有一些Java记录的实例的对象的实例大小.当我使用GraphLayout.parseInstance时,我得到一个UnsupportedOperationException,描述为"Can‘t Get field Offset on a Record Class".当使用ClassLayout.parseClass时,我得到相同的错误.

我最初使用的是Java 20,但已经降级到Java 17.我try 了Jol的最后两个版本(0.17和0.16).我try 了堆栈跟踪中的建议"无法获取字段偏移量,try 使用-Djol.magicFieldOffset=true".看起来记录在HotspotUnsafe.fieldOffset中不受支持,特别是在不安全中的第647行.

下面是一个传递和抛出异常的类似记录的类的示例.

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) {
    }
}

我做了一些搜索,以寻找将Jol与Java Records结合使用的示例,但没有找到任何东西.目前,使用我可能遗漏的一些配置设置,Jol是否可以做到这一点?

推荐答案

答案是Yes,Java对象布局确实适用于Java记录,并且需要在命令行上传递选项-Djol.magicFieldOffset=true.根据Aleksey的说法,这个选项是专门为处理记录而添加的.

我从IntelliJ运行代码,并在程序参数文本框中设置选项,而不是在vmOptions文本框(我必须首先添加它)中设置选项.将该选项添加到运行/调试配置中的vmOptions已修复该问题.

Java相关问答推荐

如何用Java表示C++类以通过FFI使用?

表格栏上的事件过滤器在PFA中不起作用

OpenJDK、4K显示和文本质量

JsonPath在多个线程中返回错误的值

强制Mockito返回null而不是emtpy list

Java自定义ThreadPool—暂停任务提交并取消当前排队任务

Select 按位运算序列

使用联接和分页的SpringBoot Spring数据JPA

错误:在Liferay7.4中找不到符号导入com.liferay.portal.kernel.uuid.PortalUUID;";

如何对多个字段进行分组和排序?

带有Health Check的Spring Boot BuildPack打破了本机映像构建过程

在执行流和相关操作时,使用Java泛型为2个方法执行相同的操作,但对象不同

如何处理两个几乎相同的XSD文件?

无限递归Java问题

为什么Instant没有从UTC转换为PostgreSQL的时区?

如何在JSP中从select中获取值并将其放入另一个select

AspectJ编织外部依赖代码,重新打包jar并强制依赖用户使用它

如何在单元测试中获得我的装饰Mapstruct映射器的实例?

当我try 返回可选时,Mock无法正常工作

当我将鼠标悬停在javafxTextArea上时,如何更改鼠标光标?