Java 的 JVM 虛擬機

作品

書籍

課程

程式集

小說集

論文集

散文集

影片集

編輯雜誌

程式人

電子書

JavaScript

計算語言學

微積分

Blender 動畫

C# 語言

系統程式

高等 C 語言

Java

Android

Verilog

Wikidot

R 統計軟體

機率統計

計算機數學

組合語言

人工智慧

開放原始碼

網路資源運用

計算機結構

相關訊息

常用工具

友站連結

在家教育

RSS

最新修改

網頁列表

簡體版

English

簡介

Java 雖然是一個程式語言,但是由於設計訴求上的跨平台目標,使得Java特別適合用虛擬機來執行。由於Java已經是廣為使用的程式語言,因此,其虛擬機也就變得相當重要。目前最常見的Java虛擬機是昇陽的 JVM 虛擬機,但是在開放原始碼界還有 Kaffe、Jikes、Novell Mono, Apache Harmony, Google Dalvik, …等數十個虛擬機,許多都可以用來編譯 Java 程式後執行,JVM並非唯一的虛擬機。

假如使用者撰寫了一個 Java 程式 (例如:HelloWorld.java),此時,可以利用 Java 的編譯指令 (例如:javac HelloWorld.java),將該程式編譯成二進位的虛擬碼,稱為 bytecode (例如: HelloWorld.class)。接著,再利用 Java 的載入指令 (例如:java HelloWorld),呼叫 Java 的虛擬機器 JVM,將該 bytecode 檔案載入到記憶體當中解譯執行。若您的電腦當中安裝了 Java 的 JDK 開發工具,您可以按照圖 1 的方式試試看如何將一個 Java 程式編譯成 bytecode,並且執行看看。

範例 1. Java 的程式與編譯執行過程

程式原始碼
class HelloWorld {
  public static void main (String[]) { 
    println("Hello World!");
  }
}    

執行過程
D:\ch10>javac HelloWorld.java

D:\ch10>java HelloWorld
Hello World!
JavaCompileRun.jpg

圖 1. Java 程式的編譯與執行方式

Java 的 Bytecode 可以直接在網路上流通,被執行前並不需要重新編譯,JVM虛擬機會利用 Bytecode 解譯器執行 bytecode,或利用即時編譯器 (Just in Time Compiler : JIT) 將 Bytecode 進一步轉換成該電腦上的機器碼執行,圖 2 顯示了 Bytecode 的這種跨平台特性。

JVM.jpg

圖 2. 利用虛擬機讓 Bytecode 跨平台執行

由於虛擬機本身就是一種軟體,所以在動態載入技術的實作特別簡單,因為載入器通常就屬於虛擬機的一部分,只要利用載入器載入目的檔後,再用虛擬機執行該目的碼即可。

舉例而言,範例 1 中的兩行Java程式會動態的載入一個由變數 name 所指定的 byte code 檔案,然後利用該檔案建立出對應的物件。這樣的技術讓 Java 程式可以在詢問使用者之後,再決定要載入哪一個類別。如此,就不需要在一開始時就將所有的函式庫載入,達成動態連結與動態載入的效果。甚至可以在需要的時候,才透過網路從另一台電腦中下載目的碼並執行,這也是當初 Java Applet 的用意,但可惜的是在瀏覽器大戰中 JVM 的技術遭到敗北的命運。但是後來Adobe Macromedia 公司的Flash技術,基本上也是一種瀏覽器中的虛擬機,而且成功的跨越瀏覽器執行,達成跨越網路執行的效果,Flash 可以視為 Java Applet 的復活版。

範例 1. Java 當中動態載入技術的範例

Class type=ClassLoader.getSystemClassLoader().loadClass(name);
Object obj = type.newInstance();

如果將 Java 與 C 語言的系統程式比較,會形成一個很好的對照,Java 的 javac 編譯器可以對照到C語言的 gcc 編譯器,bytecode 相當於虛擬機器上的目的檔,可對照到 ELF 格式的目的檔,虛擬機器 JVM 則可對照到真實的 CPU。

JavaVsC.jpg

圖 3. Java 與 C 程式的執行模式對照

在昇陽公司所提供的 Java 開發工具 JDK 中,包含反組譯器 javap,但是不包含組譯器。範例 2 顯示了 javap 反組譯器的用法,讀者可以順便觀察 java 組合語言的設計方式。

範例 2. 利用 javap 指令將 bytecode 反組譯成組合語言

指令 javap -c HelloWorld 的輸出結果
Compiled from "HelloWorld.java"
class HelloWorld extends java.lang.Object{
HelloWorld();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
  0:   getstatic  #2; //Field java/lang/System.out:Ljava/io/PrintStream;
  3:   ldc      #3; //String Hello World!
  5:   invokevirtual #4;//Method java/io/PrintStream.println:(Ljava/lang/String;)V
  8:   return
}

雖然昇陽沒有提供Java組合語言的組譯器,但是您可以在網路上找到一些像是Dr. Ron Cytron撰寫的javap 與 Jon Meyer's 撰寫的Jasmin等,都提供了bytecode的組譯功能。這些工具可以幫助有興趣的讀者進一步的理解 Java 的組合語言。

Java 語言雖然在瀏覽器的 Applet 技術上遭到失敗的命運,但卻受到許多程式設計師的青睞,使得 Java 技術流傳甚廣,並且成功的匯集了許多商業公司加入其陣營,包含 IBM、Oracle、Google等,都是支持Java語言的重量級廠商。甚至,在 Google 的手機平台 Android 當中,更使用了 Dalvik Virtual Machine (DVM),該虛擬機與昇陽的 JVM 採用了完全不同的技術,但卻可以吸收所有 Java 的程式,因為 Google 提供了從 JVM的 bytecode 轉換到 DVM 的虛擬碼之工具,可以有效的吸收 JAVA 的資源進入 Android 平台當中。

Facebook

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License