You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算Java数组的内存大小?含32位JVM场景及示例代码需求

Great question! Let's break this down clearly, covering both 32-bit HotSpot JVM array memory calculation and practical code examples for measuring Java object sizes (including arrays).

32-bit HotSpot JVM: Calculating Array Memory Size

In a 32-bit HotSpot JVM, an array's header consists of three fixed components, and the total size follows specific alignment rules:

Array Header Components (Fixed 12 Bytes)

  • Mark Word: 4 bytes (stores hash code, lock state, GC age, and other metadata)
  • Class Pointer: 4 bytes (points to the array's class metadata; no pointer compression needed in 32-bit mode)
  • Array Length: 4 bytes (stores the number of elements in the array)

Total Size Calculation Steps

  1. Calculate element total size: size of element type × array length
  2. Sum header + element size: 12 bytes + element total size
  3. Align to 8-byte boundary: HotSpot requires all object sizes to be multiples of 8 bytes in 32-bit mode. If the sum isn't a multiple of 8, padding bytes are added to reach the nearest valid size.

Examples

  • int[] arr = new int[1]: 12 + (4×1) = 16 bytes (already an 8-byte multiple, no padding)
  • int[] arr = new int[2]: 12 + (4×2) = 20 bytes → padded to 24 bytes (adds 4 padding bytes)
  • byte[] arr = new byte[3]: 12 + 3 = 15 bytes → padded to 16 bytes (adds 3 padding bytes)

Practical Code to Measure Java Object Memory Size

There are two reliable ways to calculate an object's shallow memory size (size of the object itself, excluding referenced objects): using the official Instrumentation API, or the low-level sun.misc.Unsafe (not recommended for production).

This approach uses Java's official agent mechanism for accurate, JVM-compliant measurements.

Step 1: Create the Agent Class

import java.lang.instrument.Instrumentation;

public class ObjectSizeAgent {
    private static Instrumentation instrumentation;

    // Called automatically when the JVM starts
    public static void premain(String args, Instrumentation inst) {
        instrumentation = inst;
    }

    // Returns the shallow size of the object
    public static long getObjectSize(Object obj) {
        if (instrumentation == null) {
            throw new IllegalStateException("Agent not initialized. Run with -javaagent flag.");
        }
        return instrumentation.getObjectSize(obj);
    }
}

Step 2: Create MANIFEST.MF

Create a file named MANIFEST.MF with this content:

Premain-Class: ObjectSizeAgent

Step 3: Package into a JAR

Package the agent class and manifest into a JAR (e.g., object-size-agent.jar).

Step 4: Test Class

public class ObjectSizeTest {
    public static void main(String[] args) {
        // Test a regular object
        class User {
            private int id;
            private String name;
            private boolean active;
        }
        User user = new User();
        System.out.println("User object shallow size: " + ObjectSizeAgent.getObjectSize(user) + " bytes");

        // Test arrays
        int[] intArray = new int[5];
        System.out.println("int[5] size: " + ObjectSizeAgent.getObjectSize(intArray) + " bytes");

        byte[] byteArray = new byte[7];
        System.out.println("byte[7] size: " + ObjectSizeAgent.getObjectSize(byteArray) + " bytes");
    }
}

Step 5: Run with the Agent

Execute the test class with the agent flag:

java -javaagent:object-size-agent.jar ObjectSizeTest

Unsafe provides direct memory access, but it's an internal API and may break across JVM versions or be restricted in newer Java releases.

import sun.misc.Unsafe;
import java.lang.reflect.Field;

public class UnsafeSizeCalculator {
    private static final Unsafe unsafe;

    static {
        try {
            Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
            unsafeField.setAccessible(true);
            unsafe = (Unsafe) unsafeField.get(null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException("Failed to access Unsafe", e);
        }
    }

    public static long getObjectSize(Object obj) {
        if (obj == null) return 0;
        Class<?> clazz = obj.getClass();

        // Handle arrays
        if (clazz.isArray()) {
            int length = java.lang.reflect.Array.getLength(obj);
            long headerSize = unsafe.arrayBaseOffset(clazz);
            long elementSize = unsafe.arrayIndexScale(clazz);
            long total = headerSize + (elementSize * length);
            return alignTo8Bytes(total);
        }

        // Handle regular objects
        long lastFieldOffset = 0;
        for (Field field : clazz.getDeclaredFields()) {
            if (!field.isSynthetic()) {
                long offset = unsafe.objectFieldOffset(field);
                lastFieldOffset = Math.max(lastFieldOffset, offset);
            }
        }
        long fieldSize = getFieldSize(clazz.getDeclaredFields()[clazz.getDeclaredFields().length - 1]);
        return alignTo8Bytes(lastFieldOffset + fieldSize);
    }

    private static long getFieldSize(Field field) {
        Class<?> type = field.getType();
        if (type == boolean.class || type == byte.class) return 1;
        if (type == char.class || type == short.class) return 2;
        if (type == int.class || type == float.class) return 4;
        if (type == long.class || type == double.class) return 8;
        return 4; // Reference size in 32-bit JVM
    }

    private static long alignTo8Bytes(long size) {
        final long ALIGNMENT = 8;
        return (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1);
    }

    public static void main(String[] args) {
        User user = new User();
        System.out.println("User object shallow size: " + getObjectSize(user) + " bytes");

        int[] intArray = new int[5];
        System.out.println("int[5] size: " + getObjectSize(intArray) + " bytes");
    }

    static class User {
        private int id;
        private String name;
        private boolean active;
    }
}

内容的提问来源于stack exchange,提问作者shengbang he

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:06:25