2015-06-19 31 views

回答

1

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" 
1

Java使用兩個字節碼和彙編語言。這是一個兩步過程。正如@ elliott-frisch指出的,第一步是將Java源代碼編譯爲字節碼。在運行時,JVM監視程序的哪些部分被使用了很多。如果一個方法「跑得很快」,它就被編譯成彙編語言。反過來,這本身就是一個多步驟的過程,包括許多優化,並用更快的代碼取代快速代碼。我在幾年前在BeyondJava.net中描述過這一點。

如果您可以節省45分鐘,我還建議您觀看Charles Nutter的演講。 "Down the rabbit hole"對於Java如何編譯爲彙編語言有很好的介紹。

至於你的問題:你有一些參數添加到命令啓動應用程序:

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

您也可以下載一個特殊的DLL,並將其存儲在JRE文件夾中。另請參閱Chris Newlands article關於如何爲OS X編譯此文件。

+1

已經有[如何在JVM中查看JIT編譯的代碼?](https://stackoverflow.com/questions/1503479/how-to-see-jit-compiled-code-in-jvm)提示相同的問答選項。 –