主頁 > 後端開發 > 第一章: 初始JVM

第一章: 初始JVM

2020-10-08 20:09:02 後端開發

跟很多人一樣,我一開始接觸 Java 虛擬機只是因為面試需要用到,所以硬著頭皮看看,所以很多人對于為什么要學虛擬機這個問題,他們的答案都是:因為面試, 因為裝逼 但我經過了幾年的學習和實戰,我發現其實學習虛擬機并不僅僅在于面試,而在于更深入地理解 Java 這門語言,以及為未來排查線上問題打下基礎,

img

當我想學JVM的時候,也是一臉懵逼 , 看了很多的視頻,有深,有淺,這些知識混起來,也很懵逼,所以 ,看了B站的宋紅康JVM教程,還不錯, 就寫個筆記記錄一下

第 1 章 JVM 和 Java 體系架構

1、JVM 前言

作為Java工程師的你曾被傷害過嗎?你是否也遇到過這些問題?

  1. 運行著的線上系統突然卡死,系統無法訪問,甚至直接OOM!
  2. 想解決線上JVM GC問題,但卻無從下手,
  3. 新專案上線,對各種JVM引數設定一臉茫然,直接默認吧然后就GG了
  4. 每次面試之前都要重新背一遍JVM的一些原理概念性的東西,然而面試官卻經常問你在實際專案中如何調優VM引數,如何解決GC、OOM等問題,一臉懵逼,

2、開發人員的病態

  1. 大部分Java開發人員,除了會在專案中使用到與Java平臺相關的各種高精尖技術,對于Java技術的核心Java虛擬機了解甚少,
  2. 一些有一定作業經驗的開發人員,打心眼兒里覺得SSM、微服務等上層技術才是重點,基礎技術并不重要,這其實是一種本末倒置的"病態",如果我們把核心類別庫的API比做數學公式的話,那么Java虛擬機的知識就好比公式的推導程序,
  3. 計算機系統體系對我們來說越來越遠,在不了解底層實作方式的前提下,通過高級語言很容易撰寫程式代碼,但事實上計算機并不認識高級語言

3、架構師在想甚么

架構師每天都在思考什么?

  1. 應該如何讓我的系統更快?
  2. 如何避免系統出現瓶頸?

知乎上有條帖子:應該如何看招聘資訊,直通年薪50萬+?

  1. 參與現有系統的性能優化,重構,保證平臺性能和穩定性
  2. 根據業務場景和需求,決定技術方向,做技術選型
  3. 能夠獨立架構和設計海量資料下高并發分布式解決方案,滿足功能和非功能需求
  4. 解決各類潛在系統風險,核心功能的架構與代碼撰寫
  5. 分析系統瓶頸,解決各種疑難雜癥,性能調優等

4、為什么學習 JVM

  1. 面試的需要(BATJ、TMD,PKQ等面試都愛問)
  2. 中高級程式員必備技能:專案管理、調優的需求
  3. 追求極客的精神,比如:垃圾回收演算法、JIT(即時編譯器)、底層原理

5、Java VS C++

  1. 垃圾收集機制為我們打理了很多繁瑣的作業,大大提高了開發的效率,但是,垃圾收集也不是萬能的,懂得JVM內部的記憶體結構、作業機制,是設計高擴展性應用和診斷運行時問題的基礎,也是Java工程師進階的必備能力,
  2. C語言需要自己來分配記憶體和回收記憶體,Java全部交給JVM進行分配和回收,

6、參考書籍

英文檔案規范:https://docs.oracle.com/javase/specs/index.html

中文書籍:

7、課程章節

8、TIOBE 排行榜

TIOBE 排行榜:https://www.tiobe.com/tiobe-index/

9、Java 生態圈

Java是目前應用最為廣泛的軟體開發平臺之一,隨著Java以及Java社區的不斷壯大Java 也早已不再是簡簡單單的一門計算機語言了,它更是一個平臺、一種文化、一個社區,

  1. 作為一個平臺,Java虛擬機扮演著舉足輕重的作用
  • Groovy、Scala、JRuby、Kotlin等都是Java平臺的一部分
  1. 作為一種文化,Java幾乎成為了"開源"的代名詞,
  • 第三方開源軟體和框架,如Tomcat、Struts,MyBatis,Spring等,
  • 就連JDK和JVM自身也有不少開源的實作,如openJDK、Harmony,
  1. 作為一個社區,Java擁有全世界最多的技術擁護者和開源社區支持,有數不清的論壇和資料,從桌面應用軟體、嵌入式開發到企業級應用、后臺服務器、中間件,都可以看到Java的身影,其應用形式之復雜、參與人數之眾多也令人咋舌,

10、Java的跨平臺性

  1. 每個語言都需要轉換成位元組碼檔案,最后轉換的位元組碼檔案都能通過Java虛擬機進行運行和處理
  2. 隨著Java7的正式發布,Java虛擬機的設計者們通過JSR-292規范基本實作在Java虛擬機平臺上運行非Java語言撰寫的程式,
  3. Java虛擬機根本不關心運行在其內部的程式到底是使用何種編程語言撰寫的,它只關心"位元組碼"檔案,也就是說Java虛擬機擁有語言無關性,并不會單純地與Java語言"終身系結",只要其他編程語言的編譯結果滿足并包含Java虛擬機的內部指令集、符號表以及其他的輔助資訊,它就是一個有效的位元組碼檔案,就能夠被虛擬機所識別并裝載運行,

11、位元組碼

  1. 我們平時說的java位元組碼,指的是用java語言編譯成的位元組碼,準確的說任何能在jvm平臺上執行的位元組碼格式都是一樣的,所以應該統稱為:jvm位元組碼,
  2. 不同的編譯器,可以編譯出相同的位元組碼檔案,位元組碼檔案也可以在不同的JVM上運行,
  3. Java虛擬機與Java語言并沒有必然的聯系,它只與特定的二進制檔案格式——Class檔案格式所關聯,Class檔案中包含了Java虛擬機指令集(或者稱為位元組碼、Bytecodes)和符號表,還有一些其他輔助資訊,

12、多語言混合編程

  1. Java平臺上的多語言混合編程正成為主流,通過特定領域的語言去解決特定領域的問題是當前軟體開發應對日趨復雜的專案需求的一個方向,
  2. 試想一下,在一個專案之中,并行處理用Clojure語言撰寫,展示層使用JRuby/Rails,中間層則是Java,每個應用層都將使用不同的編程語言來完成,而且,介面對每一層的開發者都是透明的,各種語言之間的互動不存在任何困難,就像使用自己語言的原生API一樣方便,因為它們最終都運行在一個虛擬機之上,
  3. 對這些運行于Java虛擬機之上、Java之外的語言,來自系統級的、底層的支持正在迅速增強,以JSR-292為核心的一系列專案和功能改進(如DaVinci Machine專案、Nashorn引擎、InvokeDynamic指令、java.lang.invoke包等),推動Java虛擬機從"Java語言的虛擬機"向 "多語言虛擬機"的方向發展,

13、自己寫個 JVM

  1. Java虛擬機非常復雜,要想真正理解它的作業原理,最好的方式就是自己動手撰寫一個!
  2. 自己動手寫一個Java虛擬機,難嗎?
  3. 天下事有難易乎?為之,則難者亦易矣;不為,則易者亦難矣

14、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

15、虛擬機介紹

15.1、虛擬機概念

所謂虛擬機(Virtual Machine),就是一臺虛擬的計算機,它是一款軟體,用來執行一系列虛擬計算機指令,大體上,虛擬機可以分為系統虛擬機和程式虛擬機,

  1. 大名鼎鼎的Virtual Box,VMware就屬于系統虛擬機,它們完全是對物理計算機的仿真,提供了一個可運行完整作業系統的軟體平臺,
  2. 程式虛擬機的典型代表就是Java虛擬機,它專門為執行單個計算機程式而設計,在Java虛擬機中執行的指令我們稱為Java位元組碼指令,
  3. 無論是系統虛擬機還是程式虛擬機,在上面運行的軟體都被限制于虛擬機提供的資源中,

15.2、Java 虛擬機

  1. Java虛擬機是一臺執行Java位元組碼的虛擬計算機,它擁有獨立的運行機制,其運行的Java位元組碼也未必由Java語言編譯而成,
  2. JVM平臺的各種語言可以共享Java虛擬機帶來的跨平臺性、優秀的垃圾回器,以及可靠的即時編譯器,
  3. Java技術的核心就是Java虛擬機(JVM,Java Virtual Machine),因為所有的Java程式都運行在Java虛擬機內部,
  4. Java虛擬機就是二進制位元組碼的運行環境,負責裝載位元組碼到其內部,解釋/編譯為對應平臺上的機器指令執行,每一條Java指令,Java虛擬機規范中都有詳細定義,如怎么取運算元,怎么處理運算元,處理結果放在哪里,

特點:

  1. 一次編譯,到處運行
  2. 自動記憶體管理
  3. 自動垃圾回收功能

16、JVM 的位置

JVM是運行在作業系統之上的,它與硬體沒有直接的互動

Java的體系結構

17、Java 的整體結構

  1. HotSpot VM是目前市面上高性能虛擬機的代表作之一,
  2. 它采用 解釋器與即時編譯器并存的架構
  3. 在今天,Java程式的運行性能早已脫胎換骨,已經達到了可以和C/C++程式一較高下的地步,
  4. 執行引擎包含三部分:解釋器,即時編譯器,垃圾回收器

18、Java 代碼執行流程

凡是能生成被Java虛擬機所能解釋、運行的位元組碼檔案,那么理論上我們就可以自己設計一套語言了

19、JVM 架構模型

Java編譯器輸入的指令流基本上是一種基于堆疊的指令集架構,另外一種指令集架構則是基于暫存器的指令集架構,具體來說:這兩種架構之間的區別:

19.1、基于堆疊的指令集架構

基于堆疊式架構的特點:

  1. 設計和實作更簡單,適用于資源受限的系統;
  2. 避開了暫存器的分配難題:使用零地址指令方式分配
  3. 指令流中的指令大部分是零地址指令,其執行程序依賴于操作堆疊, 指令集更小,編譯器容易實作
  4. 不需要硬體支持,可移植性更好,更好實作跨平臺

19.2、基于暫存器的指令級架構

基于暫存器架構的特點:

  1. 典型的應用是x86的二進制指令集:比如傳統的PC以及Android的Davlik虛擬機,
  2. 指令集架構則完全依賴硬體,與硬體的耦合度高,可移植性差
  3. 性能優秀和執行更高效
  4. 花費更少的指令去完成一項操作
  5. 在大部分情況下, 基于暫存器架構的指令集往往都以一地址指令、二地址指令和三地址指令為主,而基于堆疊式架構的指令集卻是以零地址指令為主

19.3、兩種架構的舉例

同樣執行2+3這種邏輯操作,其指令分別如下:

  • *基于堆疊的計算流程(以Java虛擬機為例):
iconst_2 //常量2入栈
istore_1
iconst_3 // 常量3入栈
istore_2
iload_1
iload_2
iadd //常量2/3出栈,执行相加
istore_0 // 结果5入栈
  • *而基于暫存器的計算流程
mov eax,2 //將eax暫存器的值設為1
add eax,3 //使eax暫存器的值加3

19.4、如何反編譯位元組碼檔案

  • 撰寫 java 代碼,編譯生成位元組碼檔案
public class StackStruTest {
    public static void main(String[] args) {
        int i = 2;
        int j = 3;
        int k = i + j;
    }
}
  • 在 .class 檔案的同級目錄下,執行反編譯

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	// 将常量 2 压入栈中
         1: istore_1	// 将常量 2 保存至变量 i 中
         2: iconst_3	// 将常量 3 压入栈中
         3: istore_2	// 将常量 3 保存至变量 j 中
         4: iload_1		// 加载变量 i
         5: iload_2		// 加载变量 j
         6: iadd		// 执行累加操作
         7: istore_3	// 加法结果保存在变量 k 中
         8: return
      LineNumberTable:
        line 10: 0
        line 11: 2
        line 12: 4
        line 22: 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
}

19.5、JVM 架構總結

  1. 由于跨平臺性的設計,Java的指令都是根據堆疊來設計的,不同平臺CPU架構不同,所以不能設計為基于暫存器的, 優點是跨平臺,指令集小,編譯器容易實作,缺點是性能下降,實作同樣的功能需要更多的指令
  2. 時至今日,盡管嵌入式平臺已經不是Java程式的主流運行平臺了(準確來說應該是HotSpot VM的宿主環境已經不局限于嵌入式平臺了),那么為什么不將架構更換為基于暫存器的架構呢?
  3. 因為基于堆疊的架構跨平臺性好、指令集小,雖然相對于基于暫存器的架構來說,基于堆疊的架構編譯得到的指令更多,執行性能也不如基于暫存器的架構好,但考慮到其跨平臺性與移植性,我們還是選用堆疊的架構

20、JVM 生命周期

20.1、虛擬機的啟動

Java虛擬機的啟動是通過引導類加載器(bootstrap class loader)創建一個初始類(initial class)來完成的,這個類是由虛擬機的具體實作指定的,

20.2、虛擬機的執行

  1. 一個運行中的Java虛擬機有著一個清晰的任務:執行Java程式
  2. 程式開始執行時他才運行,程式結束時他就停止
  3. 執行一個所謂的Java程式的時候,真真正正在執行的是一個叫做Java虛擬機的行程

20.3、虛擬機的退出

有如下的幾種情況:

  1. 程式正常執行結束
  2. 程式在執行程序中遇到了例外或錯誤而例外終止
  3. 由于作業系統用現錯誤而導致Java虛擬機行程終止
  4. 某執行緒呼叫Runtime類或System類的exit()方法,或Runtime類的halt()方法,并且Java安全管理器也允許這次exit()或halt()操作,
  5. 除此之外,JNI(Java Native Interface)規范描述了用JNI Invocation API來加載或卸載 Java虛擬機時,Java虛擬機的退出情況,

20.4、查看虛擬機行程

  • 代碼
public class StackStruTest {
    public static void main(String[] args) {
        int i = 2;
        int j = 3;
        int k = i + j;

        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hello");
    }
}
  • 趁程式還在運行的時候,趕快使用 jps 指令查看當前正在運行的行程,圖中 23756 為行程所占用的埠號

  • StackStruTest 進行執行完畢,就查看不到咯

20.5、exit() 方法原始碼

Runtime 類原始碼分析

  • Runtime 物件全域唯一,對應著下圖中的【運行時資料區】

  • 明顯的餓漢設計模式:一上來就 new 了一個 Runtime 類的實體,并且將 Runtime 類的構造器私有化了
public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

    private Runtime() {}
  • Runtime 類的 exit() 方法呼叫了 ShutDown 類的 exit() 方法
public void exit(int status) {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkExit(status);
    }
    Shutdown.exit(status);
}

ShutDown 類原始碼分析

  • exit() 方法會呼叫到本地方法 runAllFinalizers() 和 halt0()
static void exit(int status) {
    boolean runMoreFinalizers = false;
    synchronized (lock) {
        if (status != 0) runFinalizersOnExit = false;
        switch (state) {
            case RUNNING:
                state = HOOKS;
                break;
            case HOOKS:
                break;
            case FINALIZERS:
                if (status != 0) {

                    halt(status);
                } else {

                    runMoreFinalizers = runFinalizersOnExit;
                }
                break;
        }
    }
    if (runMoreFinalizers) {
        runAllFinalizers();
        halt(status);
    }
    synchronized (Shutdown.class) {

        sequence();
        halt(status);
    }
}
static void halt(int status) {
    synchronized (haltLock) {
        halt0(status);
    }
}
static native void halt0(int status);

private static native void runAllFinalizers();

System 類原始碼分析

  • System.exit() 方法呼叫了 Runtime.exit() 方法
public static void exit(int status) {
    Runtime.getRuntime().exit(status);
}

總結

  1. 呼叫 System.exit() 方法 --> 呼叫 Runtime.exit() 方法
  2. 呼叫 Runtime.exit() 方法 --> 呼叫了 ShutDown.exit() 方法

21、JVM 發展歷程

21.1、Sun Classic VM

  1. 早在1996年Java1.0版本的時候,Sun公司發布了一款名為sun classic VM的Java虛擬機,它同時也是世界上第一款商用Java虛擬機,JDK1.4時完全被淘汰,
  2. 這款虛擬機內部只提供解釋器,沒有即時編譯器,因此效率比較低,即時編譯器會把熱點代碼快取起來,那么以后使用熱點代碼的時候,效率就比較高,
  3. 如果使用JIT編譯器,就需要進行外掛,但是一旦使用了JIT編譯器,JIT就會接管虛擬機的執行系統,解釋器就不再作業,解釋器和編譯器不能配合作業,
  4. 現在Hotspot內置了此虛擬機,

21.2、Exact VM

  1. 為了解決上一個虛擬機問題,jdk1.2時,Sun提供了此虛擬機,
  2. Exact Memory Management:準確式記憶體管理
  • 也可以叫Non-Conservative/Accurate Memory Management
  • 虛擬機可以知道記憶體中某個位置的資料具體是什么型別,
  1. 具備現代高性能虛擬機的維形
  • 熱點探測(尋找出熱點代碼進行快取)
  • 編譯器與解釋器混合作業模式
  1. 只在Solaris平臺短暫使用,其他平臺上還是classic vm,英雄氣短,終被Hotspot虛擬機替換

21.3、HotSpot VM

  1. HotSpot歷史
  • 最初由一家名為"Longview Technologies"的小公司設計
  • 1997年,此公司被Sun收購;2009年,Sun公司被甲骨文收購,
  • JDK1.3時,HotSpot VM成為默認虛擬機
  1. 目前Hotspot占有絕對的市場地位,稱霸武林,
  • 不管是現在仍在廣泛使用的JDK6,還是使用比例較多的JDK8中,默認的虛擬機都是HotSpot
  • Sun/oracle JDK和openJDK的默認虛擬機
  • 因此本課程中默認介紹的虛擬機都是HotSpot,相關機制也主要是指HotSpot的GC機制,(比如其他兩個商用虛機都沒有方法區的概念)
  1. 從服務器、桌面到移動端、嵌入式都有應用,
  2. 名稱中的HotSpot指的就是它的熱點代碼探測技術,
  • 通過計數器找到最具編譯價值代碼,觸發即時編譯或堆疊上替換
  • 通過編譯器與解釋器協同作業,在最優化的程式回應時間與最佳執行性能中取得平衡

21.4、JRockit

  1. 專注于服務器端應用:它可以不太關注程式啟動速度,因此JRockit內部不包含決議器實作,全部代碼都靠即時編譯器編譯后執行,
  2. 大量的行業基準測驗顯示,JRockit JVM是世界上最快的JVM:使用JRockit產品,客戶已經體驗到了顯著的性能提高(一些超過了70%)和硬體成本的減少(達50%),
  3. 優勢:全面的Java運行時解決方案組合
  • JRockit面向延遲敏感型應用的解決方案JRockit Real Time提供以毫秒或微秒級的JVM回應時間,適合財務、軍事指揮、電信網路的需要
  • Mission Control服務套件,它是一組以極低的開銷來監控、管理和分析生產環境中的應用程式的工具,
  1. 2008年,JRockit被Oracle收購,
  2. Oracle表達了整合兩大優秀虛擬機的作業,大致在JDK8中完成,整合的方式是在HotSpot的基礎上,移植JRockit的優秀特性,
  3. 高斯林:目前就職于谷歌,研究人工智能和水下機器人

21.5、IBM的J9

  1. 全稱:IBM Technology for Java Virtual Machine,簡稱IT4J,內部代號:J9
  2. 市場定位與HotSpot接近,服務器端、桌面應用、嵌入式等多用途VM廣泛用于IBM的各種Java產品,
  3. 目前,有影響力的三大商用虛擬機之一,也號稱是世界上最快的Java虛擬機,
  4. 2017年左右,IBM發布了開源J9VM,命名為openJ9,交給Eclipse基金會管理,也稱為Eclipse OpenJ9
  5. OpenJDK -> 是JDK開源了,包括了虛擬機

21.6、KVM和CDC / CLDC Hotspot

  1. Oracle在Java ME產品線上的兩款虛擬機為:CDC/CLDC HotSpot Implementation VM KVM(Kilobyte)是CLDC-HI早期產品目前移動領域地位尷尬,智能機被Android和iOS二分天下,
  2. KVM簡單、輕量、高度可移植,面向更低端的設備上還維持自己的一片市場
  • 智能控制器、傳感器
  • 老人手機、經濟欠發達地區的功能手機
  1. 所有的虛擬機的原則:一次編譯,到處運行,

21.7、Azul VM

  1. 前面三大"高性能Java虛擬機"使用在通用硬體平臺上這里Azul VW和BEA Liquid VM是與特定硬體平臺系結、軟硬體配合的專有虛擬機:高性能Java虛擬機中的戰斗機,
  2. Azul VM是Azul Systems公司在HotSpot基礎上進行大量改進,運行于Azul Systems公司的專有硬體Vega系統上的Java虛擬機,
  3. 每個Azul VM實體都可以管理至少數十個CPU和數百GB記憶體的硬體資源,并提供在巨大記憶體范圍內實作可控的GC時間的垃圾收集器、專有硬體優化的執行緒調度等優秀特性,
  4. 2010年,Azul Systems公司開始從硬體轉向軟體,發布了自己的Zing JVM,可以在通用x86平臺上提供接近于Vega系統的特性,

21.8、Liquid VM

  1. 高性能Java虛擬機中的戰斗機,
  2. BEA公司開發的,直接運行在自家Hypervisor系統上
  3. Liquid VM即是現在的JRockit VE(Virtual Edition)
  4. Liquid VM不需要作業系統的支持,或者說它自己本身實作了一個專用作業系統的必要功能,如執行緒調度、檔案系統、網路支持等,
  5. 隨著JRockit虛擬機終止開發,Liquid vM專案也停止了,

21.9、Apache Marmony

  1. Apache也曾經推出過與JDK1.5和JDK1.6兼容的Java運行平臺Apache Harmony,
  2. 它是IElf和Intel聯合開發的開源JVM,受到同樣開源的Open JDK的壓制,Sun堅決不讓Harmony獲得JCP認證,最終于2011年退役,IBM轉而參與OpenJDK
  3. 雖然目前并沒有Apache Harmony被大規模商用的案例,但是它的Java類別庫代碼吸納進了Android SDK,

21.10、Micorsoft JVM

  1. 微軟為了在IE3瀏覽器中支持Java Applets,開發了Microsoft JVM,
  2. 只能在window平臺下運行,但確是當時Windows下性能最好的Java VM,
  3. 1997年,Sun以侵犯商標、不正當競爭罪名指控微軟成功,賠了Sun很多錢,微軟WindowsXP SP3中抹掉了其VM,現在Windows上安裝的jdk都是HotSpot,

21.11、Taobao JVM

  1. 由AliJVM團隊發布,阿里,國內使用Java最強大的公司,覆寫云計算、金融、物流、電商等眾多領域,需要解決高并發、高可用、分布式的復合問題,有大量的開源產品,
  2. 基于OpenJDK開發了自己的定制版本AlibabaJDK,簡稱AJDK,是整個阿里Java體系的基石,
  3. 基于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
  1. taobao vm應用在阿里產品上性能高,硬體嚴重依賴inte1的cpu,損失了兼容性,但提高了性能
  2. 目前已經在淘寶、天貓上線,把Oracle官方JvM版本全部替換了,

21.12、Dalvik VM

  1. 谷歌開發的,應用于Android系統,并在Android2.2中提供了JIT,發展迅猛,
  2. Dalvik VM只能稱作虛擬機,而不能稱作"Java虛擬機",它沒有遵循 Java虛擬機規范
  3. 不能直接執行Java的Class檔案
  4. 基于暫存器架構,不是jvm的堆疊架構,
  5. 執行的是編譯以后的dex(Dalvik Executable)檔案,執行效率比較高,
  6. 它執行的dex(Dalvik Executable)檔案可以通過class檔案轉化而來,使用Java語法撰寫應用程式,可以直接使用大部分的Java API等,
  7. Android 5.0使用支持提前編譯(Ahead of Time Compilation,AoT)的ART VM替換Dalvik VM,

21.13、Graal VM

  1. 2018年4月,Oracle Labs公開了GraalvM,號稱 "Run Programs Faster Anywhere",勃勃野心,與1995年java的"write once,run anywhere"遙相呼應,
  2. GraalVM在HotSpot VM基礎上增強而成的跨語言全堆疊虛擬機,可以作為"任何語言"
    的運行平臺使用,語言包括:Java、Scala、Groovy、Kotlin;C、C++、Javascript、Ruby、Python、R等
  3. 支持不同語言中混用對方的介面和物件,支持這些語言使用已經撰寫好的本地庫檔案
  4. 作業原理是將這些語言的源代碼或源代碼編譯后的中間格式,通過解釋器轉換為能被Graal VM接受的中間表示,Graal VM提供Truffle工具集快速構建面向一種新語言的解釋器,在運行時還能進行即時編譯優化,獲得比原生編譯器更優秀的執行效率,
  5. 如果說HotSpot有一天真的被取代,Graalvm希望最大,但是Java的軟體生態沒有絲毫變化,

21.14、總結

具體JVM的記憶體結構,其實取決于其實作,不同廠商的JVM,或者同一廠商發布的不同版本,都有可能存在一定差異,主要以Oracle HotSpot VM為默認虛擬機,

你只管學習,我來負責記筆記?? 關注公眾號! ,更多筆記,等你來拿,謝謝



轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/163387.html

標籤:Java

上一篇:大學計算機專業,哪些課程是必須學好的重點?

下一篇:類加載器詳解

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more