如何解释 java 中 -XX:CompileCommand="print Class::Method" 的输出
How to interpret the output of -XX:CompileCommand="print Class::Method" in java
这是我 运行 以下命令时得到的输出的摘录(40 只是 Fibonacci 程序的一个参数):
java -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand="print Fibonacci::fibonacci" 斐波那契 40
谁能解释一下每个数据的含义(我估计是字节数,比如主代码占288字节)。另外,各种类别是什么意思 - 重定位、存根代码、元数据、范围数据、范围 pc、处理程序 table 等是什么意思?
...
Compiled method (c2) 93 16 4 Fibonacci::fibonacci (22 bytes)
total in heap [0xfff8000108113dd0,0xfff8000108114440] = 1648
relocation [0xfff8000108113f00,0xfff8000108113f48] = 72
main code [0xfff8000108113f60,0xfff8000108114080] = 288
stub code [0xfff8000108114080,0xfff80001081141e0] = 352
oops [0xfff80001081141e0,0xfff80001081141e8] = 8
metadata [0xfff80001081141e8,0xfff8000108114210] = 40
scopes data [0xfff8000108114210,0xfff8000108114298] = 136
scopes pcs [0xfff8000108114298,0xfff80001081143d8] = 320
dependencies [0xfff80001081143d8,0xfff80001081143e0] = 8
handler table [0xfff80001081143e0,0xfff8000108114440] = 96
----------------------------------------------------------------------
Fibonacci.fibonacci [0xfff8000108113f60, 0xfff80001081141e0] 640 bytes
[Entry Point]
[Verified Entry Point]
[Constants]
# {method} {0xfff80001036243b8} 'fibonacci' '(I)J' in 'Fibonacci'
# parm0: I0 = int
# [sp+0x90] (sp of caller)
...
方括号之间的十六进制数字是包含数据的内存范围的开始和结束。如您所料,=
之后的数字是以字节为单位的数据大小。
关于类别:
total in heap
是整个编译后的代码和元数据。它包括所有其他类别。它实际上大于所有其他类别的总和,因为还有一堆其他字段没有在这个 table 中描述(这个 table 只描述了对象中具有可变大小的部分)。
relocation
是允许 VM 在必要时修补代码的元数据:例如,如果代码嵌入了一个对象指针,那么如果 GC 移动该对象,则需要修改该指针。它还包含有关内联缓存、对外部常量的任何引用、运行时调用等的信息。
main code
是为该方法编译的大部分本机代码。
stub code
这是与此方法相关的更多机器代码。在某些运行时事件(例如,链接或重新链接调用站点或内联缓存、去优化、异常处理...)期间,通常是用于支持主要代码的小代码段
oops
普通对象指针数组(即指向垃圾收集对象的指针)。它们可以从主代码或下面的 scopes data
中引用。
metadata
自从在 JDK 8 中移除永久代后,VM 的关于 classes 和方法的元数据不再是标准的垃圾收集 oops,因为它们仍然需要被跟踪他们有自己的部分。所以 metadata
是指向元数据对象的指针(例如代表 classes 和方法的 VM 对象)。它们也可以从主代码或下面的 scopes data
中引用。
scopes pcs
这包含允许从主要本机代码中的程序计数器转到 Java 中的代码位置的元数据:本机 PC 映射到 Java 方法和字节码索引("bci")。由于内联,单个 PC 实际上与一堆 (method, bci) 对相关联。
scopes data
这包含进一步描述这些 PC 上的 Java 虚拟机状态的元数据。它包含将 JVM 位置(例如本地或堆栈槽)映射到本机位置(例如寄存器或本机堆栈槽)的数据。这允许 VM 知道在 GC 期间在哪里寻找 oops 以及在去优化期间重建解释器的状态。
dependencies
这是编译器在编译此方法时制作的 "assumptions" 列表。这样的假设可能是"class Foo has no subclasses"。这允许 VM 知道如果以后有什么东西违反了这个假设(例如加载一个新的 class,它是前面示例中 Foo 的子 class),则需要使这个方法无效。
handler table
这是一个table,让VM知道在因为异常而展开时从哪里继续执行。
这是我 运行 以下命令时得到的输出的摘录(40 只是 Fibonacci 程序的一个参数):
java -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand="print Fibonacci::fibonacci" 斐波那契 40
谁能解释一下每个数据的含义(我估计是字节数,比如主代码占288字节)。另外,各种类别是什么意思 - 重定位、存根代码、元数据、范围数据、范围 pc、处理程序 table 等是什么意思?
...
Compiled method (c2) 93 16 4 Fibonacci::fibonacci (22 bytes)
total in heap [0xfff8000108113dd0,0xfff8000108114440] = 1648
relocation [0xfff8000108113f00,0xfff8000108113f48] = 72
main code [0xfff8000108113f60,0xfff8000108114080] = 288
stub code [0xfff8000108114080,0xfff80001081141e0] = 352
oops [0xfff80001081141e0,0xfff80001081141e8] = 8
metadata [0xfff80001081141e8,0xfff8000108114210] = 40
scopes data [0xfff8000108114210,0xfff8000108114298] = 136
scopes pcs [0xfff8000108114298,0xfff80001081143d8] = 320
dependencies [0xfff80001081143d8,0xfff80001081143e0] = 8
handler table [0xfff80001081143e0,0xfff8000108114440] = 96
----------------------------------------------------------------------
Fibonacci.fibonacci [0xfff8000108113f60, 0xfff80001081141e0] 640 bytes
[Entry Point]
[Verified Entry Point]
[Constants]
# {method} {0xfff80001036243b8} 'fibonacci' '(I)J' in 'Fibonacci'
# parm0: I0 = int
# [sp+0x90] (sp of caller)
...
方括号之间的十六进制数字是包含数据的内存范围的开始和结束。如您所料,=
之后的数字是以字节为单位的数据大小。
关于类别:
total in heap
是整个编译后的代码和元数据。它包括所有其他类别。它实际上大于所有其他类别的总和,因为还有一堆其他字段没有在这个 table 中描述(这个 table 只描述了对象中具有可变大小的部分)。relocation
是允许 VM 在必要时修补代码的元数据:例如,如果代码嵌入了一个对象指针,那么如果 GC 移动该对象,则需要修改该指针。它还包含有关内联缓存、对外部常量的任何引用、运行时调用等的信息。main code
是为该方法编译的大部分本机代码。stub code
这是与此方法相关的更多机器代码。在某些运行时事件(例如,链接或重新链接调用站点或内联缓存、去优化、异常处理...)期间,通常是用于支持主要代码的小代码段oops
普通对象指针数组(即指向垃圾收集对象的指针)。它们可以从主代码或下面的scopes data
中引用。metadata
自从在 JDK 8 中移除永久代后,VM 的关于 classes 和方法的元数据不再是标准的垃圾收集 oops,因为它们仍然需要被跟踪他们有自己的部分。所以metadata
是指向元数据对象的指针(例如代表 classes 和方法的 VM 对象)。它们也可以从主代码或下面的scopes data
中引用。scopes pcs
这包含允许从主要本机代码中的程序计数器转到 Java 中的代码位置的元数据:本机 PC 映射到 Java 方法和字节码索引("bci")。由于内联,单个 PC 实际上与一堆 (method, bci) 对相关联。scopes data
这包含进一步描述这些 PC 上的 Java 虚拟机状态的元数据。它包含将 JVM 位置(例如本地或堆栈槽)映射到本机位置(例如寄存器或本机堆栈槽)的数据。这允许 VM 知道在 GC 期间在哪里寻找 oops 以及在去优化期间重建解释器的状态。dependencies
这是编译器在编译此方法时制作的 "assumptions" 列表。这样的假设可能是"class Foo has no subclasses"。这允许 VM 知道如果以后有什么东西违反了这个假设(例如加载一个新的 class,它是前面示例中 Foo 的子 class),则需要使这个方法无效。handler table
这是一个table,让VM知道在因为异常而展开时从哪里继续执行。