您应该使用jol,这是作为 OpenJDK 项目的一部分开发的工具。
JOL(Java Object Layout)是用于分析 JVM 中对象布局方案的微型工具箱。这些工具大量使用 Unsafe、JVMTI 和 Serviceability Agent (SA) 来解码实际的对象布局、占用空间和引用。这使得 JOL 比其他依赖堆转储、规范假设等的工具更准确。
要获取基元、引用和数组元素的大小,请使用VMSupport.vmDetails()
. 在 64 位 Windows 上运行的 Oracle JDK 1.8.0_40(用于以下所有示例),此方法返回
Running 64-bit HotSpot VM.
Using compressed oop with 0-bit shift.
Using compressed klass with 3-bit shift.
Objects are 8 bytes aligned.
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
ClassLayout.parseClass(Foo.class).toPrintable()
您可以使用(可选地将实例传递给toPrintable
)来获取对象实例的浅大小。这只是该类的单个实例消耗的空间;它不包括该类引用的任何其他对象。它确实包括对象标头、字段对齐和填充的 VM 开销。对于java.util.regex.Pattern
:
java.util.regex.Pattern object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (0000 0001 0000 0000 0000 0000 0000 0000)
4 4 (object header) 00 00 00 00 (0000 0000 0000 0000 0000 0000 0000 0000)
8 4 (object header) cb cf 00 20 (1100 1011 1100 1111 0000 0000 0010 0000)
12 4 int Pattern.flags 0
16 4 int Pattern.capturingGroupCount 1
20 4 int Pattern.localCount 0
24 4 int Pattern.cursor 48
28 4 int Pattern.patternLength 0
32 1 boolean Pattern.compiled true
33 1 boolean Pattern.hasSupplementary false
34 2 (alignment/padding gap) N/A
36 4 String Pattern.pattern (object)
40 4 String Pattern.normalizedPattern (object)
44 4 Node Pattern.root (object)
48 4 Node Pattern.matchRoot (object)
52 4 int[] Pattern.buffer null
56 4 Map Pattern.namedGroups null
60 4 GroupHead[] Pattern.groupNodes null
64 4 int[] Pattern.temp null
68 4 (loss due to the next object alignment)
Instance size: 72 bytes (reported by Instrumentation API)
Space losses: 2 bytes internal + 4 bytes external = 6 bytes total
您可以使用 获取对象实例深度大小的摘要视图GraphLayout.parseInstance(obj).toFootprint()
。当然,足迹中的某些对象可能是共享的(也从其他对象引用),因此当该对象被垃圾回收时,它是可以回收的空间的过度近似。对于Pattern.compile("^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$")
(取自这个答案)的结果,jol 报告了 1840 字节的总占用空间,其中只有 72 个是 Pattern 实例本身。
java.util.regex.Pattern instance footprint:
COUNT AVG SUM DESCRIPTION
1 112 112 [C
3 272 816 [Z
1 24 24 java.lang.String
1 72 72 java.util.regex.Pattern
9 24 216 java.util.regex.Pattern$1
13 24 312 java.util.regex.Pattern$5
1 16 16 java.util.regex.Pattern$Begin
3 24 72 java.util.regex.Pattern$BitClass
3 32 96 java.util.regex.Pattern$Curly
1 24 24 java.util.regex.Pattern$Dollar
1 16 16 java.util.regex.Pattern$LastNode
1 16 16 java.util.regex.Pattern$Node
2 24 48 java.util.regex.Pattern$Single
40 1840 (total)
如果您改为使用GraphLayout.parseInstance(obj).toPrintable()
, jol 将告诉您对每个被引用对象的字段取消引用的地址、大小、类型、值和路径,尽管这通常过于详细而无用。对于正在进行的模式示例,您可能会得到以下信息。(地址可能会在运行之间发生变化。)
java.util.regex.Pattern object externals:
ADDRESS SIZE TYPE PATH VALUE
d5e5f290 16 java.util.regex.Pattern$Node .root.next.atom.next (object)
d5e5f2a0 120 (something else) (somewhere else) (something else)
d5e5f318 16 java.util.regex.Pattern$LastNode .root.next.next.next.next.next.next.next (object)
d5e5f328 21664 (something else) (somewhere else) (something else)
d5e647c8 24 java.lang.String .pattern (object)
d5e647e0 112 [C .pattern.value [^, [, a, -, z, A, -, Z, 0, -, 9, _, ., +, -, ], +, @, [, a, -, z, A, -, Z, 0, -, 9, -, ], +, \, ., [, a, -, z, A, -, Z, 0, -, 9, -, ., ], +, $]
d5e64850 448 (something else) (somewhere else) (something else)
d5e64a10 72 java.util.regex.Pattern (object)
d5e64a58 416 (something else) (somewhere else) (something else)
d5e64bf8 16 java.util.regex.Pattern$Begin .root (object)
d5e64c08 24 java.util.regex.Pattern$BitClass .root.next.atom.val$rhs (object)
d5e64c20 272 [Z .root.next.atom.val$rhs.bits [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
d5e64d30 24 java.util.regex.Pattern$1 .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs (object)
d5e64d48 24 java.util.regex.Pattern$1 .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs.val$rhs (object)
d5e64d60 24 java.util.regex.Pattern$5 .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$lhs (object)
d5e64d78 24 java.util.regex.Pattern$1 .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs.val$rhs (object)
d5e64d90 24 java.util.regex.Pattern$5 .root.next.atom.val$lhs.val$lhs.val$lhs.val$lhs (object)
d5e64da8 24 java.util.regex.Pattern$5 .root.next.atom.val$lhs.val$lhs.val$lhs (object)
d5e64dc0 24 java.util.regex.Pattern$5 .root.next.atom.val$lhs.val$lhs (object)
d5e64dd8 24 java.util.regex.Pattern$5 .root.next.atom.val$lhs (object)
d5e64df0 24 java.util.regex.Pattern$5 .root.next.atom (object)
d5e64e08 32 java.util.regex.Pattern$Curly .root.next (object)
d5e64e28 24 java.util.regex.Pattern$Single .root.next.next (object)
d5e64e40 24 java.util.regex.Pattern$BitClass .root.next.next.next.atom.val$rhs (object)
d5e64e58 272 [Z .root.next.next.next.atom.val$rhs.bits [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
d5e64f68 24 java.util.regex.Pattern$1 .root.next.next.next.atom.val$lhs.val$lhs.val$lhs (object)
d5e64f80 24 java.util.regex.Pattern$1 .root.next.next.next.atom.val$lhs.val$lhs.val$rhs (object)
d5e64f98 24 java.util.regex.Pattern$5 .root.next.next.next.atom.val$lhs.val$lhs (object)
d5e64fb0 24 java.util.regex.Pattern$1 .root.next.next.next.atom.val$lhs.val$rhs (object)
d5e64fc8 24 java.util.regex.Pattern$5 .root.next.next.next.atom.val$lhs (object)
d5e64fe0 24 java.util.regex.Pattern$5 .root.next.next.next.atom (object)
d5e64ff8 32 java.util.regex.Pattern$Curly .root.next.next.next (object)
d5e65018 24 java.util.regex.Pattern$Single .root.next.next.next.next (object)
d5e65030 24 java.util.regex.Pattern$BitClass .root.next.next.next.next.next.atom.val$rhs (object)
d5e65048 272 [Z .root.next.next.next.next.next.atom.val$rhs.bits [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
d5e65158 24 java.util.regex.Pattern$1 .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$lhs.val$lhs (object)
d5e65170 24 java.util.regex.Pattern$1 .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$lhs.val$rhs (object)
d5e65188 24 java.util.regex.Pattern$5 .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$lhs (object)
d5e651a0 24 java.util.regex.Pattern$1 .root.next.next.next.next.next.atom.val$lhs.val$lhs.val$rhs (object)
d5e651b8 24 java.util.regex.Pattern$5 .root.next.next.next.next.next.atom.val$lhs.val$lhs (object)
d5e651d0 24 java.util.regex.Pattern$5 .root.next.next.next.next.next.atom.val$lhs (object)
d5e651e8 24 java.util.regex.Pattern$5 .root.next.next.next.next.next.atom (object)
d5e65200 32 java.util.regex.Pattern$Curly .root.next.next.next.next.next (object)
d5e65220 120 (something else) (somewhere else) (something else)
d5e65298 24 java.util.regex.Pattern$Dollar .root.next.next.next.next.next.next (object)
“(其他)”条目描述了堆中不属于此对象图的其他对象。
最好的 jol 文档是 jol 存储库中的jol 示例。这些示例演示了常见的 jol 操作,并展示了如何使用 jol 来分析 VM 和垃圾收集器内部结构。