1. 程式人生 > >【JVM之記憶體與垃圾回收篇】JVM與Java體系結構

【JVM之記憶體與垃圾回收篇】JVM與Java體系結構

# JVM與Java體系結構 ## 前言 作為 Java 工程師的你曾被傷害過嗎?你是否也遇到過這些問題? 執行著的線上系統突然卡死,系統無法訪問,甚至直接 OOM(out of memory)! - 想解決線上 JVM GC 問題,但卻無從下手。 - 新專案上線,對各種 JVM 引數設定一臉茫然,直接預設吧然後就 GG 了 - 每次面試之前都要重新背一遍 JVM 的一些原理概念性的東西,然而面試官卻經常問你在實際專案中如何調優 VM 引數,如何解決 GC、OOM 等問題,一臉懵逼。 ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205045432-48031551.png) 大部分 Java 開發人員,除會在專案中使用到與 Java 平臺相關的各種高精尖技術,對於 Java 技術的核心 Java 虛擬機器瞭解甚少。 一些有一定工作經驗的開發人員,打心眼兒裡覺得 SSM、微服務等上層技術才是重點,基礎技術並不重要,這其實是一種本末倒置的“病態”。如果我們把核心類庫的 API 比做數學公式的話,那麼 Java 虛擬機器的知識就好比公式的推導過程。 計算機系統體系對我們來說越來越遠,在不瞭解底層實現方式的前提下,通過高階語言很容易編寫程式程式碼。但事實上計算機並不認識高階語言 ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205057427-352976375.png) ## 架構師每天都在思考什麼? - 應該如何讓我的系統更快? - 如何避免系統出現瓶頸? 知乎上有條帖子:應該如何看招聘資訊,直通年薪 50萬+? - 參與現有系統的效能優化,重構,保證平臺效能和穩定性 - 根據業務場景和需求,決定技術方向,做技術選型 - 能夠獨立架構和設計海量資料下高併發分散式解決方案,滿足功能和非功能需求 - 解決各類潛在系統風險,核心功能的架構與程式碼編寫 - 分析系統瓶頸,解決各種疑難雜症,效能調優等 ## 為什麼要學習JVM - 面試的需要(BATJ、TMD,PKQ 等面試都愛問) - 中高階程式設計師必備技能 - 專案管理、調優的需求 - 追求極客的精神 - 比如:垃圾回收演算法、JIT(及時編譯器)、底層原理 ## Java vs C++ 垃圾收集機制為我們打理了很多繁瑣的工作,大大提高了開發的效率,但是,垃圾收集也不是萬能的,懂得 JVM 內部的記憶體結構、工作機制,是設計高擴充套件性應用和診斷執行時問題的基礎,也是 Java 工程師進階的必備能力。 ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205110006-1941288047.png) C 語言需要自己來分配記憶體和回收記憶體,Java 全部交給 JVM 進行分配和回收。 ## 推薦書籍 ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205119943-1783375239.png) ## Java生態圈 Java 是目前應用最為廣泛的軟體開發平臺之一。隨著 Java 以及 Java 社群的不斷壯大 Java 也早已不再是簡簡單單的一門計算機語言了,它更是一個平臺、一種文化、一個社群。 - 作為一個平臺,Java 虛擬機器扮演著舉足輕重的作用 - Groovy、Scala、JRuby、Kotlin 等都是 Java 平臺的一部分 - 作為燈種文化,Java 幾乎成為了“開源”的代名詞。 - 第三方開源軟體和框架。如 Tomcat、Struts,MyBatis,Spring等。 - 就連 JDK 和 JVM 自身也有不少開源的實現,如 openJDK、Harmony。 - 作為一個社群,Java 擁有全世界最多的技術擁護者和開源社群支援,有數不清的論壇和資料。從桌面應用軟體、嵌入式開發到企業級應用、後臺伺服器、中介軟體,都可以看到 Java 的身影。其應用形式之複雜、參與人數之眾多也令人咋舌。 ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205131088-1188761743.png) 每個語言都需要轉換成位元組碼檔案,最後轉換的位元組碼檔案都能通過 Java 虛擬機器進行執行和處理 ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205137407-1691918751.png) 隨著 Java7 的正式釋出,Java 虛擬機器的設計者們通過 JSR-292 規範基本實現在 Java 虛擬機器平臺上執行非 Java 語言編寫的程式。 Java 虛擬機器根本不關心執行在其內部的程式到底是使用何種程式語言編寫的,它只關心“位元組碼”檔案。也就是說 Java 虛擬機器擁有語言無關性,並不會單純地與 Java 語言“終身繫結”,只要其他程式語言的編譯結果滿足幷包含 Java 虛擬機器的內部指令集、符號表以及其他的輔助資訊,它就是一個有效的位元組碼檔案,就能夠被虛擬機器所識別並裝載執行。 ## 位元組碼 我們平時說的 java 位元組碼,指的是用 java 語言編譯成的位元組碼。準確的說任何能在 jvm 平臺上執行的位元組碼格式都是一樣的。所以應該統稱為:jvm 位元組碼。 不同的編譯器,可以編譯出相同的位元組碼檔案,位元組碼檔案也可以在不同的 JVM 上執行。 Java 虛擬機器與 Java 語言並沒有必然的聯絡,它只與特定的二進位制檔案格式——Class 檔案格式所關聯,Class 檔案中包含了 Java 虛擬機器指令集(或者稱為位元組碼、Bytecodes)和符號表,還有一些其他輔助資訊。 ## 多語言混合程式設計 Java 平臺上的多語言混合程式設計正成為主流,通過特定領域的語言去解決特定領域的問題是當前軟體開發應對日趨複雜的專案需求的一個方向。 試想一下,在一個專案之中,並行處理用 clojure 語言編寫,展示層使用 JRuby/Rails,中間層則是 Java,每個應用層都將使用不同的程式語言來完成,而且,介面對每一層的開發者都是透明的,各種語言之間的互動不存在任何困難,就像使用自己語言的原生 API 一樣方便,因為它們最終都執行在一個虛擬機器之上。 對這些運行於 Java 虛擬機器之上、Java之外的語言,來自系統級的、底層的支援正在迅速增強,以 JSR-292 為核心的一系列專案和功能改進(如 Da Vinci Machine 專案、Nashorn 引擎、InvokeDynamic 指令、java.lang.invoke 包等),推動 Java 虛擬機器從“Java 語言的虛擬機器”向 “多語言虛擬機器”的方向發展。 ## Java發展的重大事件 - 1990 年,在 Sun 計算機公司中,由 Patrick Naughton、MikeSheridan 及 James Gosling 領導的小組 Green Team,開發出的新的程式語言,命名為 oak,後期命名為 Java - 1995 年,Sun 正式釋出 Java 和 HotJava 產品,Java 首次公開亮相。 - 1996 年 1 月 23日 sun Microsystems 釋出了 JDK 1.0。 - 1998 年,JDK1.2 版本釋出。同時,sun 釋出了 JSP/Servlet、EJB 規範,以及將 Java 分成了 J2EE、J2SE 和 J2ME。這表明了 Java 開始向企業、桌面應用和移動裝置應用 3 大領域挺進。 - 2000 年,JDK1.3 釋出,Java HotSpot Virtual Machine 正式釋出,成為 Java 的預設虛擬機器。 - 2002 年,JDK1.4 釋出,古老的 Classic 虛擬機器退出歷史舞臺。 - 2003 年年底,Java 平臺的 scala 正式釋出,同年 Groovy 也加入了 Java 陣營。 - 2004 年,JDK1.5 釋出。同時 JDK1.5 改名為 JavaSE5.0。 - 2006 年,JDK6 釋出。同年,Java 開源並建立了 openJDK。順理成章,Hotspot 虛擬機器也成為了 openJDK 中的預設虛擬機器。 - 2007 年,Java 平臺迎來了新夥伴 Clojure。 - 2008 年,oracle 收購了 BEA,得到了 JRockit 虛擬機器。 - 2009 年,Twitter 宣佈把後臺大部分程式從 Ruby 遷移到 scala,這是 Java平 臺的又一次大規模應用。 - 2010 年,oracle 收購了 sun,獲得 Java 商標和最真價值的 HotSpot 虛擬機器。此時,oracle 擁有市場佔用率最高的兩款虛擬機器 HotSpot 和 JRockit,並計劃在未來對它們進行整合:HotRockit - 2011 年,JDK7 釋出。在 JDK1.7u4 中,正式啟用了新的垃圾回收器 G1。 - 2017 年,JDK9 釋出。將 G1 設定為預設 Gc,替代 CMS - 同年,IBM 的 J9 開源,形成了現在的 open J9 社群 - 2018 年,Android 的 Java 侵權案判決,Google 賠償 oracle 計 88 億美元 - 同年,oracle 宣告 JavagE 成為歷史名詞JDBC、JMS、Servlet贈予Eclipse基金會 - 同年,JDK11 釋出,LTS 版本的 JDK,釋出革命性的 zGc,調整 JDK 授權許可 - 2019 年,JDK12 釋出,加入 RedHat 領導開發的 shenandoah GC ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205205006-1874731829.png) 在 JDK11 之前,oracleJDK 中還會存在一些 openJDK 中沒有的、閉源的功能。但在 JDK11 中,我們可以認為 openJDK 和 oracleJDK 程式碼實質上已經完全一致的程度。 ## 虛擬機器與Java虛擬機器 ### 虛擬機器 所謂虛擬機器(Virtual Machine),就是一臺虛擬的計算機。它是一款軟體,用來執行一系列虛擬計算機指令。大體上,虛擬機器可以分為系統虛擬機器和程式虛擬機器。 - 大名鼎鼎的 Visual Box,Mware 就屬於系統虛擬機器,它們完全是對物理計算機的模擬,提供了一個可執行完整作業系統的軟體平臺。 - 程式虛擬機器的典型代表就是 Java 虛擬機器,它專門為執行單個計算機程式而設計,在 Java 虛擬機器中執行的指令我們稱為 Java 位元組碼指令。 無論是系統虛擬機器還是程式虛擬機器,在上面執行的軟體都被限制於虛擬機器提供的資源中。 ### Java虛擬機器 Java 虛擬機器是一臺執行 Java 位元組碼的虛擬計算機,它擁有獨立的執行機制,其執行的 Java 位元組碼也未必由 Java 語言編譯而成。 JVM 平臺的各種語言可以共享 Java 虛擬機器帶來的跨平臺性、優秀的垃圾回器,以及可靠的即時編譯器。 Java 技術的核心就是 Java 虛擬機器(JVM,Java Virtual Machine),因為所有的 Java 程式都執行在 Java 虛擬機器內部。 Java 虛擬機器就是二進位制位元組碼的執行環境,負責裝載位元組碼到其內部,解釋/編譯為對應平臺上的機器指令執行。每一條 Java 指令,Java 虛擬機器規範中都有詳細定義,如怎麼取運算元,怎麼處理運算元,處理結果放在哪裡。 特點: - 一次編譯,到處執行 - 自動記憶體管理 - 自動垃圾回收功能 ## JVM的位置 JVM 是執行在作業系統之上的,它與硬體沒有直接的互動 ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205315451-915410546.png) Java 的體系結構 ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205321274-881391324.png) ## JVM整體結構 - HotSpot VM 是目前市面上高效能虛擬機器的代表作之一。 - 它採用直譯器與即時編譯器並存的架構。 - 在今天,Java 程式的執行效能早已脫胎換骨,已經達到了可以和 C/C++ 程式一較高下的地步。 ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205329679-1832322357.png) 執行引擎包含三部分:直譯器,及時編譯器,垃圾回收器 ## Java程式碼執行流程 ![](https://img2020.cnblogs.com/blog/1542615/202007/1542615-20200713205339294-1594734600.png) 只是能生成被 Java 虛擬機器所能解釋的位元組碼檔案,那麼理論上就可以自己設計一套程式碼了 ## JVM的架構模型 Java 編譯器輸入的指令流基本上是一種基於棧的指令集架構,另外一種指令集架構則是基於暫存器的指令集架構。具體來說:這兩種架構之間的區別: 基於棧式架構的特點 - 設計和實現更簡單,適用於資源受限的系統; - 避開了暫存器的分配難題:使用零地址指令方式分配。 - 指令流中的指令大部分是零地址指令,其執行過程依賴於操作棧。指令集更小,編譯器容易實現。 - 不需要硬體支援,可移植性更好,更好實現跨平臺 基於暫存器架構的特點 - 典型的應用是 x86 的二進位制指令集:比如傳統的 PC 以及 Android 的 Davlik 虛擬機器。 - 指令集架構則完全依賴硬體,可移植性差 - 效能優秀和執行更高效 - 花費更少的指令去完成一項操作。 - 在大部分情況下,基於暫存器架構的指令集往往都以一地址指令、二地址指令和三地址指令為主,而基於棧式架構的指令集卻是以零地址指令為主方水洋 ### 舉例 同樣執行 2+3 這種邏輯操作,其指令分別如下: 基於棧的計算流程(以 Java 虛擬機器為例): ```bash iconst_2 //常量2入棧 istore_1 iconst_3 // 常量3入棧 istore_2 iload_1 iload_2 iadd //常量2/3出棧,執行相加 istore_0 // 結果5入棧 ``` 而基於暫存器的計算流程 ```bash mov eax,2 //將eax暫存器的值設為1 add eax,3 //使eax暫存器的值加3 ``` ### 位元組碼反編譯 我們編寫一個簡單的程式碼,然後檢視一下位元組碼的反編譯後的結果 ```java /** * @author: Nemo */ public class StackStruTest { public static void main(String[] args) { int i = 2 + 3; } } ``` 然後我們找到編譯後的 class 檔案,使用下列命令進行反編譯 ```bash javap -v StackStruTest.class ``` 得到的檔案為: ``` public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=4, args_size=1 0: iconst_2 1: istore_1 2: iconst_3 3: istore_2 4: iload_1 5: iload_2 6: iadd 7: istore_3 8: return LineNumberTable: line 9: 0 line 10: 2 line 11: 4 line 12: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 args [Ljava/lang/String; 2 7 1 i I 4 5 2 j I 8 1 3 k I ``` ## 總結 由於跨平臺性的設計,Java 的指令都是根據棧來設計的。不同平臺 CPU 架構不同,所以不能設計為基於暫存器的。優點是跨平臺,指令集小,編譯器容易實現,缺點是效能下降,實現同樣的功能需要更多的指令。 時至今日,儘管嵌入式平臺已經不是 Java 程式的主流執行平臺了(準確來說應該是 HotSpotVM 的宿主環境已經不侷限於嵌入式平臺了),那麼為什麼不將架構更換為基於暫存器的架構呢? ### 棧 - 跨平臺性 - 指令集小 - 指令多 - 執行效能比暫存器差 ## JVM生命週期 ### 虛擬機器的啟動 Java 虛擬機器的啟動是通過引導類載入器(bootstrap class loader)建立一個初始類(initial class)來完成的,這個類是由虛擬機器的具體實現指定的。 ### 虛擬機器的執行 - 一個執行中的 Java 虛擬機器有著一個清晰的任務:執行 Java 程式。 - 程式開始執行時他才執行,程式結束時他就停止。 - 執行一個所謂的 Java 程式的時候,真真正正在執行的是一個叫做 Java 虛擬機器的程序。 ### 虛擬機器的退出 有如下的幾種情況: - 程式正常執行結束 - 程式在執行過程中遇到了異常或錯誤而異常終止 - 由於作業系統用現錯誤而導致 Java 虛擬機器程序終止 - 某執行緒呼叫 Runtime 類或 system 類的 exit 方法,或 Runtime 類的 halt 方法,並且 Java 安全管理器也允許這次 exit 或 halt 操作。 - 除此之外,JNI(Java Native Interface)規範描述了用 JNI Invocation API 來載入或解除安裝 Java 虛擬機器時,Java 虛擬機器的退出情況。 ## JVM發展歷程 ### Sun Classic VM - 早在 1996 年 Java1.0 版本的時候,Sun 公司釋出了一款名為 sun classic VM的 Java 虛擬機器,它同時也是世界上第一款商用 Java 虛擬機器,JDK1.4時完全被淘汰。 - 這款虛擬機器內部只提供直譯器。現在還有及時編譯器,因此效率比較低,而及時編譯器會把熱點程式碼快取起來,那麼以後使用熱點程式碼的時候,效率就比較高。 - 如果使用 JIT 編譯器,就需要進行外掛。但是一旦使用了 JIT 編譯器,JIT 就會接管虛擬機器的執行系統。直譯器就不再工作。直譯器和編譯器不能配合工作。 - 現在 hotspot 內建了此虛擬機器。 ### Exact VM 為了解決上一個虛擬機器問題,jdk1.2 時,sun 提供了此虛擬機器。 Exact Memory Management:準確式記憶體管理 - 也可以叫 Non-Conservative/Accurate Memory Management - 虛擬機器可以知道記憶體中某個位置的資料具體是什麼型別。 具備現代高效能虛擬機器的維形 - 熱點探測(尋找出熱點程式碼進行快取) - 編譯器與直譯器混合工作模式 只在 solaris 平臺短暫使用,其他平臺上還是 classic vm,英雄氣短,終被 Hotspot 虛擬機器替換 ### HotSpot VM HotSpot 歷史 - 最初由一家名為“Longview Technologies”的小公司設計 - 1997 年,此公司被 sun 收購;2009 年,Sun公司被甲骨文收購。 - JDK1.3 時,HotSpot VM 成為預設虛擬機器 目前 Hotspot 佔有絕對的市場地位,稱霸武林。 - 不管是現在仍在廣泛使用的 JDK6,還是使用比例較多的 JDK8中,預設的虛擬機器都是 HotSpot - Sun/oracle JDK 和 openJDK 的預設虛擬機器 - 因此本課程中預設介紹的虛擬機器都是 HotSpot,相關機制也主要是指 HotSpot 的 Gc 機制。(比如其他兩個商用虛機都沒有方法區的概念) 從伺服器、桌面到移動端、嵌入式都有應用。 名稱中的 HotSpot 指的就是它的熱點程式碼探測技術。 - 通過計數器找到最具編譯價值程式碼,觸發即時編譯或棧上替換 - 通過編譯器與直譯器協同工作,在最優化的程式響應時間與最佳執行效能中取得平衡 ### JRockit 專注於伺服器端應用 - 它可以不太關注程式啟動速度,因此 JRockit 內部不包含解析器實現,全部程式碼都靠即時編譯器編譯後執行。 大量的行業基準測試顯示,JRockit JVM 是世界上最快的 JVM。 - 使用 JRockit 產品,客戶已經體驗到了顯著的效能提高(一些超過了 70%)和硬體成本的減少(達 50%)。 優勢:全面的 Java 執行時解決方案組合 - JRockit 面向延遲敏感型應用的解決方案 JRockit Real Time 提供以毫秒或微秒級的 JVM 響應時間,適合財務、軍事指揮、電信網路的需要 - MissionControl 服務套件,它是一組以極低的開銷來監控、管理和分析生產環境中的應用程式的工具。 2008 年,JRockit 被 oracle 收購。 oracle 表達了整合兩大優秀虛擬機器的工作,大致在 JDK8 中完成。整合的方式是在 HotSpot 的基礎上,移植 JRockit 的優秀特性。 高斯林:目前就職於谷歌,研究人工智慧和水下機器人 ### IBM的J9 全稱:IBM Technology for Java Virtual Machine,簡稱 IT4J,內部代號:J9 市場定位與 HotSpot 接近,伺服器端、桌面應用、嵌入式等多用途VM廣泛用於 IBM 的各種 Java 產品。 目前,有影響力的三大商用虛擬機器之一,也號稱是世界上最快的 Java 虛擬機器。 2017 年左右,IBM釋出了開源 J9VM,命名為 openJ9,交給 EClipse 基金會管理,也稱為 Eclipse OpenJ9 OpenJDK -> 是JDK開源了,包括了虛擬機器 ### KVM和CDC / CLDC Hotspot oracle 在Java ME 產品線上的兩款虛擬機器為:CDC/CLDC HotSpot Implementation VM KVM(Kilobyte)是 CLDC-HI 早期產品目前移動領域地位尷尬,智慧機被 Android 和 ioS 二分天下。 KVM 簡單、輕量、高度可移植,面向更低端的裝置上還維持自己的一片市場 - 智慧控制器、感測器 - 老人手機、經濟欠發達地區的功能手機 所有的虛擬機器的原則:一次編譯,到處執行。 ### Azul VM 前面三大“高效能 Java 虛擬機器”使用在通用硬體平臺上這裡 Azu1VW 和 BEALiquid VM 是與特定硬體平臺繫結、軟硬體配合的專有虛擬機器 - 高效能Java虛擬機器中的戰鬥機。 Azul VM 是 Azu1Systems 公司在 HotSpot 基礎上進行大量改進,運行於 Azul Systems 公司的專有硬體 Vega 系統上的 java 虛擬機器。 每個 Azu1VM 例項都可以管理至少數十個 CPU 和數百 GB 記憶體的硬體資源,並提供在巨大記憶體範圍內實現可控的 GC 時間的垃圾收集器、專有硬體優化的執行緒排程等優秀特性。 2010 年,AzulSystems 公司開始從硬體轉向軟體,釋出了自己的 zing JVM,可以在通用 x86 平臺上提供接近於 Vega 系統的特性。 ### Liquid VM 高效能 Java 虛擬機器中的戰鬥機。 BEA 公司開發的,直接執行在自家 Hypervisor 系統上 Liquid VM 即是現在的 JRockit VE(Virtual Edition), Liquid VM 不需要作業系統的支援,或者說它自己本身實現了一個專用作業系統的必要功能,如執行緒排程、檔案系統、網路支援等。 隨著 JRockit 虛擬機器終止開發,Liquid vM 專案也停止了。 ### Apache Marmony Apache也曾經推出過與 JDK1.5 和 JDK1.6 相容的 Java 執行平臺 Apache Harmony。 它是 IElf 和 Inte1 聯合開發的開源 JVM,受到同樣開源的 openJDK 的壓制,Sun 堅決不讓 Harmony 獲得 JCP 認證,最終於 2011 年退役,IBM 轉而參與 OpenJDK 雖然目前並沒有 Apache Harmony 被大規模商用的案例,但是它的 Java 類庫程式碼吸納進了 Android SDK。 ### Micorsoft JVM 微軟為了在 IE3 瀏覽器中支援 Java Applets,開發了 Microsoft JVM。 只能在 window 平臺下執行。但確是當時Windows下效能最好的 Java VM。 1997 年,sun 以侵犯商標、不正當競爭罪名指控微軟成功,賠了 sun 很多錢。微軟 windowsXPSP3 中抹掉了其 VM。現在 windows 上安裝的 jdk 都是 HotSpot。 ### Taobao JVM 由 AliJVM 團隊釋出。阿里,國內使用 Java 最強大的公司,覆蓋雲端計算、金融、物流、電商等眾多領域,需要解決高併發、高可用、分散式的複合問題。有大量的開源產品。 基於 openJDK 開發了自己的定製版本 AlibabaJDK,簡稱 AJDK。是整個阿里 Java 體系的基石。 基於 openJDK Hotspot VM 釋出的國內第一個優化、深度定製且開源的高效能伺服器版 Java 虛擬機器。 - 創新的 GCIH(GCinvisible heap)技術實現了 off-heap,即將生命週期較長的 Java 物件從 heap 中移到 heap 之外,並且 Gc 不能管理 GCIH 內部的 Java 物件,以此達到降低 GC 的回收頻率和提升 Gc 的回收效率的目的。 - GCIH 中的物件還能夠在多個 Java 虛擬機器程序中實現共享 - 使用 crc32 指令實現JvM intrinsic 降低 JNI 的呼叫開銷 - PMU hardware 的 Java profiling tool 和診斷協助功能 - 針對大資料場景的 ZenGc taobao vm 應用在阿里產品上效能高,硬體嚴重依賴 inte1 的 cpu,損失了相容性,但提高了效能 目前已經在淘寶、天貓上線,把 oracle 官方 JvM 版本全部替換了。 ### Dalvik VM 谷歌開發的,應用於 Android 系統,並在 Android2.2 中提供了 JIT,發展迅猛。 Dalviky 只能稱作虛擬機器,而不能稱作“Java 虛擬機器”,它沒有遵循 Java 虛擬機器規範 不能直接執行 Java 的 Class 檔案 基於暫存器架構,不是 jvm 的棧架構。 執行的是編譯以後的 dex(Dalvik Executable)檔案。執行效率比較高。 - 它執行的 dex(Dalvik Executable)檔案可以通過 class 檔案轉化而來,使用 Java 語法編寫應用程式,可以直接使用大部分的 Java API等。 Android 5.0 使用支援提前編譯(Ahead of Time Compilation,AoT)的 ART VM 替換 Dalvik VM。 ### Graal VM 2018 年 4 月,oracle Labs 公開了 GraalvM,號稱 "Run Programs Faster Anywhere",勃勃野心。與 1995 年 java 的”write once,run anywhere"遙相呼應。 GraalVM 在 HotSpot VM 基礎上增強而成的跨語言全棧虛擬機器,可以作為“任何語言” 的執行平臺使用。語言包括:Java、Scala、Groovy、Kotlin;C、C++、Javascript、Ruby、Python、R等 支援不同語言中混用對方的介面和物件,支援這些語言使用已經編寫好的本地庫檔案 工作原理是將這些語言的原始碼或原始碼編譯後的中間格式,通過直譯器轉換為能被 Graal VM 接受的中間表示。Graal VM 提供 Truffle 工具集快速構建面向一種新語言的直譯器。在執行時還能進行即時編譯優化,獲得比原生編譯器更優秀的執行效率。 如果說 HotSpot 有一天真的被取代,Graalvm 希望最大。但是 Java 的軟體生態沒有絲毫變化。 ### 總結 具體 JVM 的記憶體結構,其實取決於其實現,不同廠商的 JVM,或者同一廠商釋出的不同版本,都有可能存在一定差異。主要以 oracle HotSpot VM 為預設虛