在JVM中编译代码?

有什么方法可以查看JVM在JVM中生成的本机代码?


假设您使用Sun Hotspot JVM(即Oracle提供的java.com上的那个),则可以添加标志

-XX:+ PrintOptoAssembly

运行代码时。 这将打印出由JIT编译器生成的优化代码,并将剩下的代码排除在外。

如果你想看到整个字节码,包括未优化的部分,请添加

-XX:CompileThreshold =#

当你运行你的代码。

在这里你可以阅读更多关于这个命令和JIT的功能。


一般用法

正如其他答案所解释的那样,您可以使用以下JVM选项运行:

-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly

过滤一个特定的方法

您还可以使用以下语法过滤特定的方法:

-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod

笔记:

  • 您可能需要根据操作系统等将第二个参数放在引号内
  • 如果方法被内联,你可能会错过一些优化
  • 如何在Windows上安装所需的库

    如果您正在运行Windows,则此页面提供有关如何构建和安装使其工作所需的hsdis-amd64.dllhsdis-i386.dll的说明。 我们在下面复制并扩展该页面的内容*以供参考:


    在哪里获得预构建的二进制文件

    您可以从fcml项目下载适用于Windows的预构建二进制文件

  • hsdis-amd64.dll
  • hsdis-i386.dll
  • 如何在Windows上构建hsdis-amd64.dllhsdis-i386.dll

    该版本的指南是在Windows 8.1 64位上使用64位Cygwin编写的,并生成hsdis-amd64.dll

  • 安装Cygwin。 在Select Packages屏幕上,添加以下软件包(通过展开Devel类别,然后在每个软件包名称旁边的Skip标签上单击一次):

  • make
  • mingw64-x86_64-gcc-core (仅用于hsdis-amd64.dll
  • mingw64-i686-gcc-core (仅用于hsdis-i386.dll
  • diffutils (在Utils类别中)
  • 运行Cygwin终端。 这可以使用安装程序创建的桌面或开始菜单图标来完成,并且会创建您的Cygwin主目录(默认情况下为C:cygwinhome<username>C:cygwin64home<username> ) 。

  • 下载最新的GNU binutils源码包并将其内容提取到您的Cygwin主目录。 在撰写本文时,最新的软件包是binutils-2.25.tar.bz2 。 这应该会导致一个名为binutils-2.25的目录(或任何最新版本)在您的Cygwin主目录中。
  • 转到JDK 8更新存储库,选择与已安装的JRE版本相对应的标签,然后单击bz2,以下载OpenJDK源代码。 将hsdis目录(在srcsharetools找到)提取到您的Cygwin主目录。
  • 在Cygwin终端中,输入cd ~/hsdis
  • 要构建hsdis-amd64.dll ,请输入

    make OS=Linux MINGW=x86_64-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25

    要构建hsdis-i386.dll ,请输入

    make OS=Linux MINGW=i686-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25

    无论哪种情况,请使用您下载的binutils版本替换2.25OS=Linux是必要的,因为尽管Cygwin是类似Linux的环境,但hsdis makefile无法识别它。

  • ./chew: No such file or directory将失败并显示消息./chew: No such file or directorygcc: command not found 。 在文本编辑器(如Wordpad或Notepad ++)中编辑<Cygwin home directory>hsdisbuildLinux-amd64bfdMakefile以将SUBDIRS = doc po (行342,如果使用binutils 2.25)更改为SUBDIRS = po 。 重新运行先前的命令。
  • 现在可以通过将它从hsdisbuildLinux-amd64hsdisbuildLinux-i586复制到您的JRE的binserverbinclient目录来安装DLL。 您可以通过搜索java.dll在您的系统上找到所有这些目录。

    奖励提示:如果您更喜欢Intel -XX:PrintAssemblyOptions=intel语法到AT&T,请在您使用的任何其他PrintAssembly选项旁边指定-XX:PrintAssemblyOptions=intel

    *页面许可是Creative Commons


    你需要一个hsdis插件来使用PrintAssembly 。 一个方便的选择是基于FCML库的hsdis插件。

    它可以针对类UNIX系统进行编译,在Windows上,您可以使用Sourceforge上FCML下载部分提供的预建库:

    在Windows中安装:

  • 提取dll(可在hsdis-1.1.2-win32-i386.zip和hsdis-1.1.2-win32-amd64.zip中找到)。
  • 将dll复制到存在java.dll地方(使用Windows搜索)。 在我的系统上,我发现它在两个位置:
  • C:Program FilesJavajre1.8.0_45binserver
  • C:Program FilesJavajdk1.8.0_45jrebinserver
  • 在Linux中安装:

  • 下载源代码,解压缩它
  • cd <source code dir>
  • ./configure && make && sudo make install
  • cd example/hsdis && make && sudo make install
  • sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/lib/amd64/hsdis-amd64.so
  • sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/jre/lib/amd64/hsdis-amd64.so
  • 在我的系统上,JDK位于/usr/lib/jvm/java-8-oracle
  • 如何运行它:

    java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly 
    -XX:+LogCompilation -XX:PrintAssemblyOptions=intel,mpad=10,cpad=10,code 
    -jar fcml-test.jar
    

    其他配置参数:

    代码在助记符之前打印机器代码。
    英特尔使用英特尔语法。
    gas使用AT&T汇编程序语法(兼容GNU汇编程序)。
    dec以十进制值形式显示IMM和位移。
    mpad = XX填充指令的助记符部分。
    cpad = XX填充机器代码。
    seg显示默认段寄存器。
    零在HEX文字的情况下显示前导零。

    英特尔语法是Windows的默认语法,而AT&T是GNU / Linux的默认语法。

    有关更多详细信息,请参阅FCML库参考手册

    链接地址: http://www.djcxy.com/p/15183.html

    上一篇: compiled code in JVM?

    下一篇: How do I create a file and write to it in Java?