浅谈JAVA VM 发展

標題:淺談 Java VM 發展
作者:Jim Huang (黃敬群)
版權宣告:允許在保留作者、出處,以及本宣告的前提下,以任何人類可讀之形式
          自由散佈
最後更新:Apr 16, 2004

                             淺談 Java VM 發展
                                  Jim Huang 
                                            

略為整理筆者對 Java VM 實作的心得,與諸位分享,在本文後半部將專注於若干
Open Source Java VM 專案的探討,筆者本身是 KaffeVM [1] 開發者,很希望本文
能對看倌有所幫助,更期待您的來信指教,藉由技術交流,讓 KaffeVM 有更好的發
展。
  [1] http://www.kaffe.org/


■ JVM (Java Virtual Machine) 與 Java 韌體

Java VM 為一個虛擬的平台,把這個平台加以硬體實作,即 materialized 後,就是
Java chip。簡單來說,它就是一顆貨真價實的 CPU,假若我們不需完整 CPU 複雜的
設計,一樣可以將它弄成 co-processor,如此一來,就不須要在 x86 或 Sun Sparc
上用 Java VM 來模擬,而是直接把 Java bytecode「餵給」Java chip 上執行。這
就是早先 Sun 稱為 picoJava 的技術,當然,隨著各軟硬體廠商的投入,引入更複
雜的技術,但原則上觀念還是一致的。
                                                                             
「模擬」既然非真,當然在效率上就較吃虧了,所以就常給人 Java 執行超慢、超耗
資源的印象,其實那是指 Virtual Machine 的效能。為了改進 JVM 效能,使用許多
技術加速,其中最重要的莫如 JIT (Just In Time) Compiler (及時編譯器,注意:
不要跟「即時」[realtime] 搞混) 與 HotSpot 的 Adaptive Compiler 等 dynamic
compilation 技術。

Java Chip 是 Optimized for Java 的 OOP、exption-handling、memory/garbage
collection 的特製 chip,而 x86 (即傳統 CPU) 並沒有針對 C++ 所編譯的 machine
code 中的 new/exception-handling/memory allocation/late-binding 作硬體支援
的最佳化動作。
                                                                             
拜 VLSI 之賜,memory allocation 以及 garabage collection 的動作可交由硬體
來實作。在 modem 或電視中,用以數位類比轉換的 DSP (數位訊號處理) chip 而言
,有所謂的 bit-reverse (作 FFT [快速傅立葉轉換] 用的),倘若以一般 x86 來做
這個動作,起碼慢 10 倍以上。又如以往的浮點運算,比整數運算慢了 20 ~ 30 倍
,但因有了浮點加速器的出現,浮點運算的速度可為整數運算的 1.3 倍!

前述提到將 JVM 以 co-processor 形式實作的方式,可以參考 Nazomi Communica-
tions [2] 公司的產品,他們推出一套 Java 加速晶片,這個代號為 JA108 的產品
專門針對 2G/2.5G 或 3G 的手機使用。不需要加裝額外的記憶體,只需將這 JA 208
IC 植入原有系統設計中,便可大幅提升 Java 應用程式效率達 15 至 60 倍。
  [2] http://www.nazomi.com/

接著,筆者在 Pentium III 上運作 MS-Windows 2000 進行以下實驗:(原始碼與
machine code 的對照)

c++ 的 virtaul method calling:
  ┌──────────────────────────┐
  │21:    testx -> setx(20); // testx 是一個指標物件   │
  │──────────────────────────│
  │00401091   push      00000014                       │
  │00401093   mov       eax,dword ptr [testx]          │
  │00401096   mov       eax,dword ptr [eax]            │
  │00401098   mov       ecx,dword ptr [testx]          │
  │0040109b   call      dword ptr [eax]                │
  └──────────────────────────┘
  不算 argument 4 個指令

c 的一般 call:
  ┌───────────────────────────┐
  │  good()                                              │
  │───────────────────────────│
  │0040109f   call      @ILT+0(?good@@YAXH@Z) (00401000) │
  │004010a4   add       esp,00000004                     │
  └───────────────────────────┘
  不算 argument 2 個指令

java 的 virtual call:
  ┌───────────────────────────┐
  │my.getData(33);                                       │
  │───────────────────────────│
  │  aload_2                                             │
  │  bipush 33                                           │
  │  invokevirtual #9             │
  └───────────────────────────┘
  不算 argument 2 個指令.
                                                                             
c++ 的 constructor:
  ┌────────────────────────────┐
  │test *testx = new test();                               │
  │────────────────────────────│
  │00401056   push      00000008                           │
  │00401058   call      ??2@YAPAXI@Z (00401184)            │
  │0040105d   add       esp,00000004                       │
  │00401060   mov       dword ptr [ebp-0c],eax             │
  │00401063   cmp       dword ptr [ebp-0c],00000000        │
  │00401067   je        main+00000030 (0040107d)           │
  │0040106d   mov       ecx,dword ptr [ebp-0c]             │
  │00401070   call      @ILT+15(??0test@@QAE@XZ) (0040100f)│
  │00401075   mov       dword ptr [testx],eax              │
  │00401078   jmp       main+00000037 (00401084)           │
  │0040107d   mov       dword ptr [testx],00000000         │
  └────────────────────────────┘
  11 個指令
                                                                             
C++ destructor:
  ┌───────────────────────────┐
  │delete testx;                                         │
  │───────────────────────────│
  │004010a7   mov       eax,dword ptr [testx]            │
  │004010aa   mov       dword ptr [ebp-10],eax           │
  │004010ad   mov       eax,dword ptr [ebp-10]           │
  │004010b0   mov       dword ptr [ebp-14],eax           │
  │004010b3   mov       eax,dword ptr [ebp-14]           │
  │004010b6   push      eax                              │
  │004010b7   call      ??3@YAXPAX@Z (00401194)          │
  │004010bc   add       esp,00000004                     │
  └───────────────────────────┘
  8 個指令

java 的 constructor:
  ┌───────────────────────────┐
  │my my1 = new my();                                    │
  │───────────────────────────│
  │new #2                                      │
  │invokenonvirtual #11 ()V>            │
  └───────────────────────────┘
  2 個指令

由此可發現,對動態配置物件的操作而言,Java 一個 method call 只要一個
machine code,但用 x86 相對需要 4 個,這是 Java 在指令集層面直接支援所致。
我們顯而易見 Java 的一個優勢 —─ 目的碼很小,可輕易置於資源困窘的家電設備
中,再加上許多現成的 APIs 可進行呼叫、繼承的使用,簡潔的程式碼就可發揮強大
的力量。


■ 執行引擎

Java VM 的核心是執行引擎,其行為模式依據指令集的定義,JLS (Java Language
Specification) 詳細規範了當執行 bytecode 指令會作什麼動作,但並未規範如何
實作,因為這是實作者的責任。執行時期,執行引擎以執行緒 (thread) 的形式存在
,如此的執行緒可直譯 bytecode 或間接的透過 JIT Compiler 來產生 native code
。執行引擎會依序從 bytecode 中取出 opcode 與 operant,依據 JLS 規範執行相
關動作,接著再取下一個 opcode,直到 method 返回或是丟出 exception。這部份
筆者不打算提太多,因為市面已經有頗多優秀的書籍可供參考,列個書目作參考:

探討一般性的 Java VM 運作機制:
1.《Java Virtual Machine》 O'Reilly 出版
    作者:Jon Meyer & Troy Dwning
    有中譯本:《Java 虛擬機器》,由國內 Java 權威蔡學鏞所譯
2.《Inside the Java 2 Virtual Machine》 McGraw-Hill 出版
    作者:Bill Venners
    如果覺得上一本過於抽象,那 Venners 寫的這本書應該很合您胃口,閱讀時請
    搭配書附光碟,有互動式 Java Applet 解說書中的 JVM 概念,作者的網頁 [3]
    相當豐富的資料整理。本書雖有中文翻譯本,但強烈建議別花冤枉錢,因為謬誤
    百出。
      [3] http://www.artima.com/insidejvm/resources/

專注於嵌入式 JVM 設計:
《深入嵌入式Java虛擬機器-Inside KVM》
    作者:胡岳偉 (Mango Hu)
    幾乎是世面上唯一本探討 Java KVM 實作的書籍,的確是相當寶貴的參考。不過
    ,需要留意的是,作者直接挖出 KVM 的原始程式碼,是否經過充分授權,值得
   商榷。


■ Java VM 效能探討

目前商業 Java VM 效能最突出的產品是 BEA 的 JRockit [4]。JRockit 主要對
server-side 應用做了很多改進,並且 Intel 協助 IA32 與 IA64 平台的最佳化,
於是,在多項 benchmark上 (SPECjbb 和 SPECjAppServer) 上,JRockit 遙遙領先
群雄。BEA 是一家引領 J2EE 技術的重量級廠商,在 Enterprise 領域除了優越的技
術外,當然要有強健高效能的 Java VM,於是 BEA 就買下 JRockit了,在許多高階
應用都可見到 JRockit VM 的蹤跡。BEA 網站上有篇由 Joakim Dahlstedt 執筆的文
章,闡述 Java VM 的效能表現其實可以打破許多人眼鏡的:[Java - A Slow
Language? It Depends on What You're Talking About] [5]。
  [4] http://www.jrockit.com/
  [5] http://dev2dev.bea.com/products/wljrockit81/articles/Dahlstedt.jsp

Joakim Dahlstedt 的來頭可不小,是 JRockit VM 的主要設計者,現任 BEA System
裡頭 Java Runtime Group 的技術長,這篇文章並非老王賣瓜,相反的,Joakim 要
我們明瞭,評斷 Java VM "benchmark" (效能評比) 的方式需要調整,主要是基於以
下幾項:

  1.一般的 benchmark 比較僅僅是 micro-benchmark level,不能推廣到 system-
    level。
  2.軟體產業開發方式發生了很大的變化,大量使用 class library、framework、
    Application server,乃至 Web services。援引舊的 benchmark 僅能針對其中
    個別 software stack,卻不能進行 system-level 的全面分析,如此的衡量本
    身就有問題。
  3.Java VM 本身的 Dynamic Optimization,可依據最真實的 profiling 數據調整
    元件,使其針對效能進行重組。
  4.最後,新的 CPU 架構,像是 Intel EPIC 可能更適合於 Dynamic Optimization
    ,而非傳統 static compiler。在 EPIC 的架構下,compiler 對效能的影響相
    當大,compiler 有責任選擇平行處理的指令集,而非像傳統 Pentium 引入自動
    的 out-of-order 亂序執行支援,這意味著,軟體支配了 EPIC 的效能,這對
    static compiler 是不利的,因為僅能從 bytecode 取得固定的統計與符號,卻
    未能對真實 profiling 作規劃。

Joakim 的結論給予我們很好的啟發:

   "In conclusion, ..., but I hope I've convinced you that using runtime
    systems like Sun Microsystems' HotSpot or BEA WebLogic JRockit Java
    is not slow or inefficient, and that the performance of a large-scale
    system built with Java may be superior to that of the same system
    built using C."

IBM 的 JDK 曾經一度是最佳性能的 Java VM,但 Sun JDK 1. 4的性能已與 IBM JDK
1.3 相當,其 server 版採用更積極的 JIT 和 GC (Garbage Collection) 技術,尤
其是針對 SMP 的應用提供最適合該硬體架構與多執行緒處理的 GC。

在另一方面,IBM 將內部的 Jalapeno JVM 研究計畫 [6] 的成果以 Open Source 授
權釋出的 JikesRVM 計畫 [7],提供一個測試許多 JIT 與 GC 等技術與演算法的參
考實作平台。IBM Rearch 將 JikesRVM 視作 JIT 方面的一個 research infrastru-
cture,在網站上羅列了相當豐富的論文可參考 。筆者參考了 JikesRVM 的研究方向
,認為 JIT Compiler 發展趨勢可列出以下:
  1. 類似於 Hotspot [8] 整合 base interpreter、profiling,以及 adaptive
     compiler 三種技術的途徑。
  2. 動態 profiling 技術,從簡單的 counter-based algorithm 進化到
     performance monitoring event。
  3. 應用靜態 compiler 中更 aggressive 的編譯技術 (對 JIT Compiler 而言,
     編譯時間已是次要問題),產生最佳化原生碼 (native code)。
  4. 應用 inter-procedural 分析,例如 escape analysis 可以 remove synchro-
     nization 和實施 stack allocation。
  5. 參考 Runtime 所獲得的資訊 (主要是 metadata 和 dynamic allocation),產
     生最佳化原生碼。
 
  [6] http://www.research.ibm.com/jalapeno/
  [7] http://www-124.ibm.com/developerworks/oss/jikesrvm/
  [8] http://java.sun.com/products/hotspot/

接著,我們來看看 Sun 的 Hotspot 技術。提到 Hotspot 不能不提 Henry Massalin
這位先驅,Henry 的博士論文在 Java Glossary 的 HotSpot 的解釋 [9] 中被譽為
"the mother of all self-modifying code",同時,HotSpot 也是 "builds heavily
on work done in a PhD thesis by Henry Massalin"。

  [9] http://mindprod.com/jgloss/hotspot.html

Java 最初的實作是透過直譯器 (interpreter),但這並非意味 Java 一定被解譯執
行的。早期的 Java VM 的確是逐一指令的解譯,因此效能極不理想,於是引入了
JIT 等關鍵技術,而 HotSpot 可說下個世代的 JIT。據 Sun 官方文獻指出,使用
HotSpot 的 Java VM 在 Runtime 時期已經很難分辨 Java bytecode 是否被 JVM 解
釋執行了,因為 HotSpot 實際上是把 Java 的bytecode 編譯成原生碼執行了。

實際上,在 HotSpot 設計中,有兩個技術是相當重要的,也就是所謂 dynamic
compilation 和 profiling。HotSpot 對 bytecode 的編譯,並非在程式執行前預先
編譯的 (這種傳統的方式相對而言稱為 static compilation),相反的,是在程式執
行過程中,以 HotSpot 內建的編譯器做動態的編譯,早期的 JIT(Just In Time) 其
實也是如此的概念,不過沒有 HotSpot 來得全面性。

那麼,HotSpot 是如何動態編譯 Java bytecode 呢﹖HotSpot 採用一個高度彈性的
設計,內部維護了 Profile Monitor,專門監視程式執行中,判斷程式片段中使用的
頻率高寡,並依據對性能影響的程度,交付於若干演算法處理。HotSpot 對於那些對
程式執行時效率影響較大的程式碼片段,特稱為 hot spot (特別以小寫書寫,避免
與 HotSpot 混淆),HotSpot 會這些片段動態編譯成原生碼,同時,會依據之前
profiling 的結果,對這些原生碼進行最佳化,從而提高執行效率。相反的,如果執
行頻率較低的程式碼片段,HotSpot 就沒必要花時間做動態編譯,只需要以直譯器執
行即可。

整體而論,在 HotSpot 下,Java bytecode 是以解譯的方式被載入到 JavaVM 中,
但是 HotSpot 立刻會依據某些程式碼片段執行的狀態,獲知其中對效能影響最大的
部分,透過動態編譯與最佳化處理,建立原生碼,於是,接下來的執行過程中就可獲
得相當程度的效能提昇。我們可以得知,HotSpot 對 bytecode 的執行有以下三種處
理方式:
  - 直譯 (不動態編譯)
  - 部分動態編譯
  - 依據 profiling 結果做動態編譯與最佳化處理
至於程式哪部分只做直譯、部分動態編譯,以及哪部分做何種最佳化處理,則全程由
Profile Monitor 決定。

採用 dynamic compilation 會比傳統的 static compilation 帶來什麼優點呢?撇
開跨平台需求不論,dynamic compilation 在許多方面優越於傳統的途徑,特別是
profiling 的能力。過去 static compilation 很難精準的預知程式執行中究竟何處
才是最需要最佳化處理的部分,僅能透過內建的 template 來建構 micro-level 的
最佳化程式碼。相反的,dynamic compilation 可獲悉最真實的 profiling 表現,
依據需求動態調整,這在日後處理器逐漸軟體化的發展趨勢而言,更顯得重要,因為
過去硬體的工作逐漸移轉到軟體來做,compiler optimization 的責任就格外沈重了
,像是前述 Intel EPIC 架構。

另一個典型的例子,稱為 method inlining。無論是在 C++ 或是 Java 中,呼叫
(invoke) method 是很消耗系統資源的,系統必須維護堆疊操作,以符合預期的
calling convention。於是,有人提出把原本需要做 method invocation 的處理,
改用 inline 的方式,「嵌入」到原本呼叫的地方,如此一來,就只是單純的循序執
行,也不會有堆疊操作。但是,method inlining 的方式對 C++ 與 Java 一類的物
件導向語言來說,編譯器很難有很好的實作方式,因為需要兼顧物件導向的特徵,尤
其是維持 dynamic binding 性質。static compiler 其實可以把 C++/Java 中屬性
為 private 與 static 的 method 做 method inlinng,但是一旦有 overridden 或
dynamic binding 時,static compiler 無法得知實際上的執行狀況,就會保守的不
予實施 inlining。這個難題,恰好可被 HotSpot 一類 dynamic compilation 的設
計迎刃而解,因為 Profiling Monitor 對 method invocation 的狀況可以掌握,當
然可精準的得知 Runtime 中,RTTI (Run-Time Type Identification) 可協助
HotSpot 處理 method inlining,因此,在 server-side 應用這種重複進行某項目
執行時,可獲得頗大的效能提昇。

Sun 的文獻也指出,在某些狀況下,Java 的應用程式甚至可比傳統的 C 程式還快。

以目前發展而言,JIT Compiler 的成本主要在於 profiling 與 dynamic compila-
tion 兩項。理想而言,這兩項成本應該視為 constantant time,於是許多研究論文
相繼提出,以作為效能改進。特製為 JIT Compiler 使用、精度不需很高的 Java
Runtime profiling 可參考〈A Portable Samplling-Based Profiler for Java
Virtual Machines〉[10],該論文提出採用 sampling 的方式來做近似分析。而至於
Dynamic compilation 的 overhead 可以用漸進式最佳化的方式來減少,在 Sun 的
HotSpot 白皮書已有詳盡的介紹。

  [10] http://www.stanford.edu/~jwhaley/papers/javagrande00.pdf

總而言之,Java 效能議題主要分以下層面探討:

  - 一般性
    VM 與 JIT 間的互動、bytecode to IR translation、IR to machine IR
    translation,以及 code generation/formatting

  - 與平台架構無關 (machine-independent) 的最佳化
    CSE、loop invariant code motion、inlining、speculative inlining、
    method specialization,以及 multiversion code

  - 與平台架構相關 (machine-dependent) 的最佳化
    Local/Global register allocation、instruction selection、instruction
    scheduling,以及 code/data alignment

  - Java 語言層面的最佳化
    Rangecheck elimination、checkcast/instanceof removal、type propagation
    、optimizations enabled due to strong typing

  - Garbage Collection
    Precise/imprecise/copying/generational/incremental

  - 平行向量化處理 (vectorization)
    應用 RISC 工作站的平行處理指令,或是如 Intel 提出的 MMX 與 SSE 指令集 


■ Linux 平台的 Java VM

在早期的 Sun Java VM 實作中,執行緒的支援主要透過 Green Thread 的 light-
weight thread 實作的,這可以確保 Java VM 在異質性的作業系統仍可有限度的執
行緒支援,然而,這導致效率的低落,畢竟不是直接使用作業系統的 Multi-thread-
ing 機制。

目前 Sun Linux JDK 已用 native thread 改寫過,而 Linux 的 multi-threadded
能力在 IBM 等大廠的投入改進,主要有以下兩種形式:

  1. NGPT ─ Next Generation Posix Threads
     將多個 Java thread 映射 (mapping) 到少點 kernael thread

  2. NPTL ─ Native Posix Thread Library
     將每個 Java thread 映射 (mapping) 到一個 kernel thread,以最佳化
     kernel thread

其中,NGPT [11] 是 IBM 的一項 Open Source 計畫,衍生自 GNU Pth 計畫 [12],
NGPT 透過 patch Linux Kernel 2.4 與 glibc 的方式來提供支援。NPTL 則是
Linux Kernel 2.6 中重要設計,可參閱〈The Native POSIX Thread Library for
Linux〉[13] 與〈Linux: Native POSIX Threading Library (NPTL)〉[14] 這兩份
經典文獻。

  [11] http://www-124.ibm.com/developerworks/oss/pthreads/
  [12] http://www.gnu.org/software/pth/
  [13] http://people.redhat.com/drepper/nptl-design.pdf
  [14] http://kerneltrap.org/node/view/422

接下來的篇幅,筆者將介紹曾接觸過的 Open Source JavaVM 實作。

- Kaffe ( http://www.kaffe.org/ )
   
Kaffe 算是這個領域中老字號的專案,從 1996 年 Tim Wilkinson 完成最初的架構
至今已經七年歷史了。Kaffe 一開始是 Tim Wilkinson 在英國發展的 clean-room
JavaVM 實作,所謂 cleanroom,就是在不參考 Sun JDK 實作的前提下,自行開發另
一個相容的實作品,那時的 Kaffe 是 BSD-like 授權方式釋出的。1997 年,Tim
Wilkinson 與 Peter Mehlitz 創立一家專注於 JavaVM 實作的公司,Transvirtual
Technologies (TVT),成功的把 Kaffe 商業化,從那時候開始,Kaffe 有兩個版本
:一個是 GPL 授權的 Open Source 實作,也就是 Kaffe.org,另外則是 TVT 內部
維護的 Custom Edition,奠定了 Open Source 與商業發展的典範。

Kaffe VM 設計的理念在於高度的移植能力以及開放 (clean-room 實作,不必受限於
Sun 的發行授權) 發展,由於 Transvirtual Kaffe 的成功,許多以 KaffeVM 為基
礎的研究專案相繼提出,讓許多嶄新的概念可藉由 Kaffe 實現。KaffeVM 的移植能
力有多好呢?已經證實能支援 70 餘種平台,甚至包含 JIT 引擎。

Transvirtual Technologies 在 1997 年成立以來,就一直活躍於嵌入式裝置的領域
,而在 2000 年開始更將其開發的 Kaffe VM 整合 Debian Linux,設計出一個稱為
PocketLinux 的平台,其核心架構就是 Linux 和 Kaffe VM (特稱 Language Engine
),上面跑的,可都是貨真價實的 Java 程式。PocketLinux 是個相當特殊的操作系
統,以 GNU Debian/Linux 為主架構,上跑 Kaffe VM 與 3rd-party open source
library 的整合環境,為手持裝置提供 Web Browser、Synchronization、Media
Player,以及 peer-to-peer 解決方案,此外,PocketLinux 另一個特點就是透過
XML 把 Kaffe 與 Linux 系統服務進行包裝,開發者只需要透過 XML 就可以呼叫系
統提供的功能。
                                                                               
儘管是針對手持裝置,Kaffe VM 算是最接近完整功能的 Java VM,幾乎能與 JDK
1.2 相容,也支援 Personal Java 規格,但不支援 J2ME 的 Profiles。Kaffe VM
的定位不僅是 small footprint Java VM,更是全功能的嵌入式 JavaVM,藉此充分
發揮 Java 在分散式環境的威力。

很不幸的,在 2001 年與 2002 年之間,Transvirtual 公司面臨極大的轉變。首先
是 Kaffe.org 的主要維護者 Edouard Parmelan 在 2001 年去世,該年年尾,Tim
Wilkinson,也就是 Transvirtual 的 CEO 決定離開公司。面臨技術人員與資金的瞬
間短缺,Peter Mehlitz 繼任 CEO 後,決定放棄 Open Source 發展路線,改變為純
粹的商業公司,於是,將 PocketLinux 重新命名為 XOE,並且不再 Open Source,
Kaffe.org 頓時成為無人領養的孤兒,停頓於 Kaffe 1.0.6 的版本。然而,Peter
Mehlitz 的舉動還是拯救不了公司的財務狀況。

在 Transvirtual 解散前夕,員工 Jim Pick 在 March 12, 2002
宣布將接手維護 Kaffe.org,並且將致力進行 Kaffe Custom Edition (也稱為 Kaffe
Pro) 與 Open Source 版本的整合,呼籲開發者協助下個 release,也就是 1.0.7
的出現。2002 年中,Transvirtual 結束營運,但是不意味著 Kaffe 的沒落,相反
的,在 Jim Pick 的領導下,Kaffe.org 成功的獲得重生,並且與其他 Open source
java VM 專案共享開發資源,例如 GNU Classpath 與 GCJ。

截至今日,許多重量級的應用程式已經可在 KaffeVM 運作了,例如 JBoss、Tomcat、
Jetty,以及 Eclipse IDE。

- Japhar ( http://www.japhar.org/ )

Japher 實作大部分的 JDK 1.1 特徵,但不包含 JIT Compiler。自 June 19, 2002
釋出 0.11 版後,就沒有發展了,原本的開發者轉換到 GNU Classpath 專案。

- GNU Classpath ( http://www.classpath.org )

發起於 1998 年的 GNU Classpath 在今日已經成為許多 Open Source JavaVM 專案
的標準。GNU Classpath 事實上並非 Java VM,而是提供 Java VM 所需要的 API 實
作,GNU Classpath 的地位之於 Java VM,好比 libc 之於 C 程式。在 2000 年前
,GNU Classpath 一開始 (0.00 版) 只支援 Japhar,並且開發相當遲緩,幾乎同一
個時間,RedHat/Cygnus 發起 GCJ (GCC for Java) 的專案,許多開發者的努力開始
進行整合。隨後 Mark Wielaard 接任維護者的重任後,GNU Classpath 的趨近成熟
,Classpath::JVM [13] 有份目前採納 GNU Classpath 成果的專案清單。

  [13] http://www.gnu.org/software/classpath/stories.html

- GNU GCJ (GCC for Java, http://gcc.gnu.org/java/ )
- ORP (Open Runtime Platform, http://orp.sourceforge.net/ )
- Wonka ( http://www.acunia.com/wonka/ )
- IBM JikesRVM ( http://www-124.ibm.com/developerworks/oss/jikesrvm/ )

IBM JikesRVM 衍生是內部的研究計畫,Jalapeno。Jalapeno 是建構於 AIX/PowerPC
、Linux/PowerPC、OS X/PowerPC,以及 Linux/IA-32 等平台的實驗性 Java VM 實
作,爾後,IBM 將內部 Jalapeno JVM 研究計畫的成果以 Open Source 授權釋出,
並成立的 JikesRVM 計畫,提供一個測試許多 JIT 與 GC 等技術與演算法的參考實
作平台。JikesRVM 在其架構設計上一直是獨樹一格,傳統的 Java VM 實作上,核心
主要仍以 C/C++ 為主,但是 JikesRVM 的核心除了平台相依的部分外,其他絕大多
數都以 Java 語言實作,也就是說,JikesRVM 可以是 self-contained 的,正如
FAQ 所提及的:

  "Jikes RVM is unique in that it is the first self-bootstrapped virtual
   machine written entirely in the Java programming language, i.e., its
   Java code runs on itself, without requiring a second virtual machine."

在發展前期,JikesRVM 仍使用 IBM 內部的 core Java APIs class library,這部
分並非 Open Source 的,這也令人詬病 IBM 的半調子開放態度。但自從 JikesRVM
2.2.1 開始 (April 7, 2003),JikesRVM 可直接使用 GNU Classpath 的成果,這也
是說轉變一個完全 Open Source 的 Java VM 研究計畫。然而,由於 JikesRVM 絕大
部分的核心在建構時,仍需要一個 Java Runtime,所以開發者還需要安裝 Sun JDK
一類的非 Open Source Java VM,但最近終於有所改觀。自從 2.3.2 版 (March 17,
2004) 開始,我們可以使用 GPL 授權的 KaffeVM 作為 JikesRVM 的 boot-straping
Java VM,這是 Open Source Java VM 另一項成果累積的展示,可參考 JikesRVM
User Guide [14]。

  [14] http://www-124.ibm.com/developerworks/oss/jikesrvm/userguide/HTML/
       Bootstrapping_with_Kaffe.html

- JamVm ( http://jamvm.sourceforge.net/ )
- JC VM ( http://jcvm.sourceforge.net/ )

你可能感兴趣的:(Java)