栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在JVM HotSpot中使用-XX:+ UnlockDiagnosticVMOptions -XX:CompileCommand = print选项

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在JVM HotSpot中使用-XX:+ UnlockDiagnosticVMOptions -XX:CompileCommand = print选项

这些说明适用于Linux(Ubuntu 10.04.4 LTS),但应适用于您的OS。在下载Oracle JDK
7u3
并适当设置了您

JAVA_HOME
PATH
环境变量之后,执行以下步骤检查可用选项:

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

您应该看到

UnlockDiagnosticVMOptions
CompileCommand
并且
PrintAssembly
选项可用。使用该
CompileCommand
选项还将启用该
PrintAssembly
选项。但是,您将需要使用HotSpot反汇编程序插件
PrintAssembly
才能工作。没有它,您可能会看到类似以下的内容:

$ java -versionjava 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' MainCompilerOracle: print *Main.mainJava HotSpot(TM) Server VM warning: printing of assembly pre is enabled; turning on DebugNonSafepoints to gain additional outputCompiled method (c2)      68    1 %Main::main @ 4 (49 bytes) total in heap  [0xb3a97548,0xb3a979ec] = 1188 relocation     [0xb3a97610,0xb3a97624] = 20 main pre      [0xb3a97640,0xb3a97840] = 512 stub pre      [0xb3a97840,0xb3a97850] = 16 oops[0xb3a97850,0xb3a97858] = 8 scopes data    [0xb3a97858,0xb3a97898] = 64 scopes pcs     [0xb3a97898,0xb3a979e8] = 336 dependencies   [0xb3a979e8,0xb3a979ec] = 4Could not load hsdis-i386.so; library not loadable; PrintAssembly is disabledOopMapSet contains 1 OopMaps

要获取HotSpot反汇编程序插件,您需要对其进行构建。查看OpenJDK
7u2源,hsdis插件自述文件说:

要将插件与JVM一起使用,您需要一个可以加载它的新版本。如果JVM的产品模式不接受-XX:+ PrintAssembly,则您没有足够新的版本。

要构建该项目,需要[GNU binutils]副本。

从理论上讲,它应该可以在Windows上构建,但是事实证明,要在Windows上创建一个可运行的GNU构建环境是困难的。

上面我们已经确认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 <sysdep.h>+#include <errno.h> #include <libiberty.h> #include <bfd.h> #include <dis-asm.h>

跑步

make
成功了。现在,只需将
hsdis-i386.so
hsdis
build
目录中的插件复制到Oracle JDK 7u3
jre/lib/i386
目录。

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

$ java -server -XX:+UnlockDiagnosticVMOptions '-XX:CompileCommand=print,*Main.main' MainCompilerOracle: print *Main.mainJava HotSpot(TM) Server VM warning: printing of assembly pre is enabled; turning on DebugNonSafepoints to gain additional outputCompiled method (c2)      68    1 %Main::main @ 4 (49 bytes) total in heap  [0xb3999548,0xb39999ec] = 1188 relocation     [0xb3999610,0xb3999624] = 20 main pre      [0xb3999640,0xb3999840] = 512 stub pre      [0xb3999840,0xb3999850] = 16 oops[0xb3999850,0xb3999858] = 8 scopes data    [0xb3999858,0xb3999898] = 64 scopes pcs     [0xb3999898,0xb39999e8] = 336 dependencies   [0xb39999e8,0xb39999ec] = 4Loaded disassembler from [snip]/jdk1.7.0_03/jre/lib/i386/hsdis-i386.soDecoding 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 0x0OopMapSet 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;    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/497618.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号