Java 获取对象实例的字节大小

有些时候,我们需要获取 Java 对象的字节大小,来进行一些判断处理。

那么,应该如何获取 Java 对象的字节大小呢?

参考地址:in-java-what-is-the-best-way-to-determine-the-size-of-an-object

ObjectSizeCalculator 类

对于 JDK8,jdk.nashorn.internal.ir.debug.ObjectSizeCalculator

System.out.println(ObjectSizeCalculator.getObjectSize(new Object()));

如果 maven 打包时,提示没有 ObjectSizeCalculator 类,则需要引入 nashorn.jar 依赖:

<dependency>
   <groupId>javafx</groupId>
   <artifactId>nashorn</artifactId>
   <version>${java.version}</version>
   <scope>system</scope>
   <systemPath>${java.home}/lib/ext/nashorn.jar</systemPath>
</dependency>

也可能出现:

Could not initialize class jdk.nashorn.internal.ir.debug.ObjectSizeCalculator$CurrentLayout
java.lang.NoClassDefFoundError: Could not initialize class jdk.nashorn.internal.ir.debug.ObjectSizeCalculator$CurrentLayout
        at jdk.nashorn.internal.ir.debug.ObjectSizeCalculator.getObjectSize(ObjectSizeCalculator.java:122)

则需要添加 -javaagent:/java-app-dir/approot/lib/nashorn-1.8.jar

自行编写 ObjectSizeCalculator

Twitter 用于计算深度对象大小的实用程序。 它考虑了不同的内存模型(32 位,压缩 oops,64 位),填充,子类填充,在圆形数据结构和数组上正常工作。

可以编译 ObjectSizeCalculator.java 这个.java 文件,它没有外部依赖。

序列化后获取大小

序列化方法可能是大多数 JVM 的良好近似。 最简单的方法如下:

public int getSize(Serializable ser) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(ser);
    oos.close();
    return baos.size();
}

如果您有具有公共引用的对象,则不会给出正确的结果,并且序列化的大小将不总是与内存中的大小匹配,但它是一个很好的近似值。