一个 Java 对象到底占多少字节?字段怎么排?压缩指针与对齐设置改变什么?JDK 27 的紧凑对象头省多少?这篇用 JOL 看布局,再用真实堆占用核对。
-- Object:实例大小 16 字节
-- Empty:实例大小 16 字节
-- A:实例大小 32 字节
偏移 12 大小 4 int i
偏移 16 大小 8 long l
偏移 24 大小 1 byte b
偏移 28 大小 4 java.lang.Object o
-- Integer:实例大小 16 字节
偏移 12 大小 4 int value
-- Long:实例大小 24 字节
偏移 16 大小 8 long value
-- Boolean:实例大小 16 字节
偏移 12 大小 1 boolean value
-- 数组头:int[0] 实例大小 16;byte[1] 24;byte[8] 24;byte[9] 32;long[3] 40;Object[3] 32
[0 8 (object header: mark) N/A, 8 4 (object header: class) N/A, 25 3 (alignment/padding gap), Instance size: 32 bytes, Space losses: 3 bytes internal + 0 bytes external = 3 bytes total] -- P(声明顺序见源码):实例大小 24
ps@12 pb@14 pl@16
-- C(声明顺序见源码):实例大小 40
ps@12 pb@14 cb@15 pl@16 ci@24 cc@28 cz@30 co@32
-- D(声明顺序见源码):实例大小 48
i1@12 l1@16 d1@24 f1@32 s1@36 c1@38 z2@40 b1@41 z1@42 o1@44
声明顺序:P: pb, pl, ps;C: cb, ci, co, cz, cc;D: z1, b1, s1, c1, i1, f1, l1, d1, o1, z2 默认 A 实例大小 32;字段 i@12 l@16 b@24 o@28 ;Object[3] 32;Integer 16;int[0] 16;Long 24;Q{int x; int y} 24
-XX:-UseCompressedOops A 实例大小 40;字段 i@12 l@16 b@24 o@32 ;Object[3] 40;Integer 16;int[0] 16;Long 24;Q{int x; int y} 24
-XX:-UseCompressedClassPointers A 实例大小 40;字段 l@16 i@24 b@28 o@32 ;Object[3] 40;Integer 24;int[0] 24;Long 24;Q{int x; int y} 24
两个都关 A 实例大小 40;字段 l@16 i@24 b@28 o@32 ;Object[3] 48;Integer 24;int[0] 24;Long 24;Q{int x; int y} 24
-XX:ObjectAlignmentInBytes=16 A 实例大小 32;字段 i@12 l@16 b@24 o@28 ;Object[3] 32;Integer 16;int[0] 16;Long 32;Q{int x; int y} 32
-Xmx33g(超过压缩指针上限) A 实例大小 40;字段 i@12 l@16 b@24 o@32 ;Object[3] 40;Integer 16;int[0] 16;Long 24;Q{int x; int y} 24
-Xmx31g A 实例大小 32;字段 i@12 l@16 b@24 o@28 ;Object[3] 32;Integer 16;int[0] 16;Long 24;Q{int x; int y} 24int[1000] 4016 字节(每元素 4.0) Integer[1000](装箱,值 1000..1999) 20016 字节(每元素 20.0) ArrayList<Integer> 1000 个 20976 字节(每元素 21.0) LinkedList<Integer> 1000 个 40032 字节(每元素 40.0) HashMap<Integer,Integer> 1000 项 72256 字节(每元素 72.3) HashSet<Integer> 1000 个 56288 字节(每元素 56.3) TreeMap<Integer,Integer> 1000 项 72048 字节(每元素 72.0) String "hello" 48 字节(每元素 48.0) String 200 个字符的 Latin-1 字符串 240 字节(每元素 240.0)
JDK 21 默认 类 A:每个实例实测 34.85 字节 JDK 21 默认 类 Q:每个实例实测 26.85 字节 JDK 21 -XX:-UseCompressedOops 类 A:每个实例实测 46.85 字节 JDK 21 -XX:-UseCompressedOops 类 Q:每个实例实测 30.85 字节
JDK 21 默认 偏移 ['A b@24 i@12 l@16 o@28', 'Q x@12 y@16', '数组数据起点 int[] 16,Object[] 16'];实测每个实例 A 34.85 字节,Q 26.85 字节 JDK 27 默认 偏移 ['A b@20 i@16 l@8 o@24', 'Q x@8 y@12', '数组数据起点 int[] 12,Object[] 12'];实测每个实例 A 35.89 字节,Q 19.89 字节 JDK 27 -XX:-UseCompactObjectHeaders 偏移 ['A b@24 i@12 l@16 o@28', 'Q x@12 y@16', '数组数据起点 int[] 16,Object[] 16'];实测每个实例 A 35.89 字节,Q 27.89 字节 JDK 27 -XX:+UseCompactObjectHeaders 偏移 ['A b@20 i@16 l@8 o@24', 'Q x@8 y@12', '数组数据起点 int[] 12,Object[] 12'];实测每个实例 A 35.89 字节,Q 19.89 字节