jvm 如何检查Java代码的汇编输出?

tzdcorbm  于 2022-11-07  发布在  Java
关注(0)|答案(2)|浏览(151)

我发现这个问题在C++中得到了解答:
How do you get assembler output from C/C++ source in gcc?

t5fffqht

t5fffqht1#

Java同时使用字节码和汇编语言机器码。这是一个两步的过程。第一步是将Java源代码编译成字节码,正如@elliott-frisch指出的。在运行时,JVM会观察程序的哪些部分被频繁使用。如果一个方法“热运行”,它就会被编译成机器码。这本身又是一个多步的过程。包括许多优化和用更快的代码替换快速的代码,几年前我在BeyondJava.net中描述过这一点。
如果你能抽出45分钟,我也建议你看Charles Nutter的演讲。"Down the rabbit hole"很好地介绍了Java如何编译为汇编语言。
至于你的问题:您必须向启动应用程序的命令添加一些参数:

javaw.exe -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly Adder

你还必须下载一个特殊的DLL并将其存储在jre文件夹中。另请参阅Chris Newlands article了解如何为OSX编译此文件。

omhiaaxx

omhiaaxx2#

Java使用字节码。最相似的是javap,根据链接的Oracle文档,javap命令反汇编一个或多个类文件。其输出取决于所使用的选项。*

package com.stackoverflow;

class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

如果我把它编译成Main.class,然后运行javap -v Main.class,我得到

Classfile /home/efrisch/workspace/StackOverflow/bin/com/stackoverflow/Main.class
  Last modified Jun 18, 2015; size 553 bytes
  MD5 checksum de4f987e783aa0f145e7245269504028
  Compiled from "Main.java"
class com.stackoverflow.Main
  minor version: 0
  major version: 52
  flags: ACC_SUPER
Constant pool:
   #1 = Class              #2             // com/stackoverflow/Main
   #2 = Utf8               com/stackoverflow/Main
   #3 = Class              #4             // java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          // java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          // "<init>":()V
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/stackoverflow/Main;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Fieldref           #17.#19        // java/lang/System.out:Ljava/io/PrintStream;
  #17 = Class              #18            // java/lang/System
  #18 = Utf8               java/lang/System
  #19 = NameAndType        #20:#21        // out:Ljava/io/PrintStream;
  #20 = Utf8               out
  #21 = Utf8               Ljava/io/PrintStream;
  #22 = String             #23            // Hello, World!
  #23 = Utf8               Hello, World!
  #24 = Methodref          #25.#27        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #25 = Class              #26            // java/io/PrintStream
  #26 = Utf8               java/io/PrintStream
  #27 = NameAndType        #28:#29        // println:(Ljava/lang/String;)V
  #28 = Utf8               println
  #29 = Utf8               (Ljava/lang/String;)V
  #30 = Utf8               args
  #31 = Utf8               [Ljava/lang/String;
  #32 = Utf8               SourceFile
  #33 = Utf8               Main.java
{
  com.stackoverflow.Main();
    descriptor: ()V
    flags:
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/stackoverflow/Main;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #22                 // String Hello, World!
         5: invokevirtual #24                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 5: 0
        line 6: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  args   [Ljava/lang/String;
}
SourceFile: "Main.java"

相关问题