• 使用 Instrumentation API
  • Java 提供了 Instrumentation API 来实现对 JVM 内存的监控和管理。可以使用 Instrumentation API 来获取对象的大小。在代码中,需要使用 getObjectSize 方法来获取对象的大小,例如:

    import java.lang.instrument.Instrumentation;
    public class ObjectSizeFetcher {
        private static volatile Instrumentation instrumentation;
        public static void premain(String args, Instrumentation instrumentation) {
            ObjectSizeFetcher.instrumentation = instrumentation;
        public static long getObjectSize(Object obj) {
            if (instrumentation == null) {
                throw new IllegalStateException("Instrumentation is null");
            return instrumentation.getObjectSize(obj);
    

    在使用 getObjectSize 方法时,需要首先通过 premain 方法来传入 Instrumentation 实例。在 JVM 启动时,可以使用 -javaagent 参数来指定 premain 类,例如:

    -javaagent:path/to/ObjectSizeFetcher.jar
    

    这样就可以使用 getObjectSize 方法来获取对象的大小了。

  • 使用 Object 定义的 hashCode 方法
  • 在 Java 中,每个对象都有一个默认的 hashCode 方法,可以用来获取对象的哈希码。在 HotSpot JVM 中,对象的哈希码存储在对象头中,占用 32 位(64 位 JVM 占用 64 位),其中低 26 位用于哈希码,高 6 位用于标识对象的类型信息和其他状态信息。因此,可以通过计算对象哈希码所占用的字节数,来估算对象的大小,例如:

    public static int getObjectSize(Object obj) {
        return Integer.BYTES + obj.hashCode();
    

    在这个方法中,我们假设 Integer.BYTES 占用 4 个字节,加上对象哈希码所占用的字节数即可。

    需要注意的是,这种方法只是一个估算,因为对象的哈希码可能会被 JVM 进行优化,例如使用指针压缩等技术,这样就会导致实际占用的内存大小与计算出的大小不同。

  • 使用 MemoryMXBean
  • Java 还提供了 MemoryMXBean 来获取 JVM 的内存信息。可以使用 getHeapMemoryUsage 方法来获取 JVM 当前堆内存的使用情况,然后通过分配一个新的对象并测量其大小,再减去该对象实际占用的内存大小,就可以得到对象本身占用的内存大小,例如:

    import java.lang.management.ManagementFactory;
    import java.lang.management.MemoryMXBean;
    import java.lang.management.MemoryUsage;
    public static long getObjectSize(Object obj) {
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
        long before = heapMemoryUsage.getUsed();
        Object dummy = new Object();
        long after = heapMemoryUsage.getUsed();
        return Math.round((after - before) / 100.0);
    

    在这个方法中,我们先通过 getHeapMemoryUsage

  • 互联网先驱者
  •