java decvm_java – 如何使用-XX:UnlockDiagnosticVMOptions -XX:CompileCommand =打印选项与JVM HotSpot...

这些说明适用于Linux(Ubuntu 10.04.4 LTS),但应适用于您的操作系统。下载

Oracle JDK 7u3并正确设置您的JAVA_HOME和PATH环境变量后,执行以下操作以检查可用选项:

java -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version

您应该看到UnlockDiagnosticVMOptions,CompileCommand和PrintAssembly选项可用。使用CompileCommand选项也将启用PrintAssembly选项。但是,您将需要PrintAssembly的HotSpot反汇编程序插件才能正常运行;没有它,你可能会看到如下所示:

$ java -version

java version "1.7.0_03"

Java(TM) SE Runtime Environment (build 1.7.0_03-b04)

Java HotSpot(TM) Server VM (build 22.1-b02, mixed mode)

$ java -server -XX:+UnlockDiagnosticVMOptions '-XX:CompileCommand=print,*Main.main' Main

CompilerOracle: print *Main.main

Java HotSpot(TM) Server VM warning: printing of assembly code is enabled; turning on DebugNonSafepoints to gain additional output

Compiled method (c2) 68 1 % Main::main @ 4 (49 bytes)

total in heap [0xb3a97548,0xb3a979ec] = 1188

relocation [0xb3a97610,0xb3a97624] = 20

main code [0xb3a97640,0xb3a97840] = 512

stub code [0xb3a97840,0xb3a97850] = 16

oops [0xb3a97850,0xb3a97858] = 8

scopes data [0xb3a97858,0xb3a97898] = 64

scopes pcs [0xb3a97898,0xb3a979e8] = 336

dependencies [0xb3a979e8,0xb3a979ec] = 4

Could not load hsdis-i386.so; library not loadable; PrintAssembly is disabled

OopMapSet contains 1 OopMaps

要获得HotSpot反汇编程序插件,您将需要构建它。看看OpenJDK 7u2源码,hsdis plugin readme说:

To use the plugin with a JVM, you need a new version that can load it.

If the product mode of your JVM does not accept -XX:+PrintAssembly,

you do not have a version that is new enough.

To build this project you [need] a copy of GNU binutils to build against.

In theory this should be buildable on Windows but getting a working

GNU build environment on Windows has proven difficult.

以上我们已经确认,Oracle JDK 7u3支持PrintAssembly。我遵循hsdis插件自述指令,下载GNU binutils 2.22,将其放在hsdis build / binutils目录中并运行make。这最终产生了以下错误:

hsdis.c:32:20: error: sysdep.h: No such file or directory

为了纠正这一点,我用以下补丁更改了hsdis.c:

diff -r 6259c6d3bbb7 src/share/tools/hsdis/hsdis.c

--- a/src/share/tools/hsdis/hsdis.c Mon Dec 12 23:08:01 2011 -0800

+++ b/src/share/tools/hsdis/hsdis.c Thu Feb 23 09:26:37 2012 -0500

@@ -29,7 +29,7 @@

#include "hsdis.h"

-#include

+#include

#include

#include

#include

然后运行make成功。现在只需将hsdis构建目录中的hsdis-i386.so插件复制到Oracle JDK 7u3 jre / lib / i386目录。

现在可以看到反汇编的代码:

$ java -server -XX:+UnlockDiagnosticVMOptions '-XX:CompileCommand=print,*Main.main' Main

CompilerOracle: print *Main.main

Java HotSpot(TM) Server VM warning: printing of assembly code is enabled; turning on DebugNonSafepoints to gain additional output

Compiled method (c2) 68 1 % Main::main @ 4 (49 bytes)

total in heap [0xb3999548,0xb39999ec] = 1188

relocation [0xb3999610,0xb3999624] = 20

main code [0xb3999640,0xb3999840] = 512

stub code [0xb3999840,0xb3999850] = 16

oops [0xb3999850,0xb3999858] = 8

scopes data [0xb3999858,0xb3999898] = 64

scopes pcs [0xb3999898,0xb39999e8] = 336

dependencies [0xb39999e8,0xb39999ec] = 4

Loaded disassembler from [snip]/jdk1.7.0_03/jre/lib/i386/hsdis-i386.so

Decoding compiled method 0xb3999548:

Code:

[Disassembling for mach='i386']

[Entry Point]

[Verified Entry Point]

[Constants]

# {method} 'main' '([Ljava/lang/String;)V' in 'Main'

0xb3999640: call 0xb6ff8510 ; {runtime_call}

0xb3999645: data32 xchg %ax,%ax

0xb3999648: mov %eax,-0x3000(%esp)

0xb399964f: push %ebp

0xb3999650: sub $0x38,%esp

0xb3999656: mov %ecx,%esi

0xb3999658: mov 0x4(%esi),%ebp

0xb399965b: mov 0x8(%esi),%edi

0xb399965e: mov (%ecx),%esi

0xb3999660: mov %ecx,(%esp)

0xb3999663: call 0xb7078cf0 ;*iload_3

[snip]

0xb399983e: hlt

0xb399983f: hlt

[Exception Handler]

[Stub Code]

0xb3999840: jmp 0xb39981e0 ; {no_reloc}

[Deopt Handler Code]

0xb3999845: push $0xb3999845 ; {section_word}

0xb399984a: jmp 0xb397e220 ; {runtime_call}

0xb399984f: .byte 0x0

OopMapSet contains 1 OopMaps

#0

OopMap{off=468}

我使用的测试类是:

public class Main {

public static void main(final String[] args) {

long x = 0;

for (int i = 0; i < 1000000; i++) {

x += calculate(i);

}

System.out.println("x=" + x);

}

private static long calculate(final int i) {

return (long)i * (long)i;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值