【JVM學習】——JVM與JAVA體系結構

1、Java生態圈

隨着Java以及Java社區的不斷壯大,Java也早已再也不是簡簡單單的一門計算機語言了,它更是一個平臺、一種文化、一個社區。java

  • 做爲一個平臺,Java虛擬機扮演着舉足輕重的做用編程

    • Groovy、Scala、JRuby、Kotlin等都是Java平臺的一部分。
  • 做爲一種文化,Java幾乎成爲了「開源」的代名詞。bootstrap

    • 第三方開源軟件和框架。如Tomcat、Struts,MyBatis,Spring等。
    • 就連JDK和JVM自身也有很多開源的實現,如openJDK、Harmony。
  • 做爲一個社區緩存

    • Java擁有全世界最多的技術擁護者和開源社區支持,有數不清的論壇和資料。
    • 應用普遍,從桌面應用軟件、嵌入式開發到企業級應用、後臺服務器、中間件,均可以看到Java的身影。

每一個語言都須要轉換成字節碼文件,最後轉換的字節碼文件都能經過Java虛擬機進行運行和處理。安全

隨着Java7的正式發佈,Java虛擬機的設計者們經過JSR-292規範基本實如今Java虛擬機平臺上運行非Java語言編寫的程序。bash

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語言的虛擬機」向 「多語言虛擬機」的方向發展。

2、虛擬機與Java虛擬機

2.1 虛擬機

虛擬機(Virtual Machine),就是一臺虛擬的計算機。它是一款軟件,用來執行一系列虛擬計算機指令。大致上,虛擬機能夠分爲系統虛擬機程序虛擬機

  • 大名鼎鼎的Visual Box,Mware就屬於系統虛擬機,它們徹底是對物理計算機的仿真,提供了一個可運行完整操做系統的軟件平臺。
  • 程序虛擬機的典型表明就是Java虛擬機,它專門爲執行單個計算機程序而設計,在Java虛擬機中執行的指令咱們稱爲Java字節碼指令。

不管是系統虛擬機仍是程序虛擬機,在上面運行的軟件都被限制於虛擬機提供的資源中。

2.2 Java虛擬機

Java虛擬機是一臺執行Java字節碼的虛擬計算機,它擁有獨立的運行機制,其運行的Java字節碼也未必由Java語言編譯而成。

JVM平臺的各類語言能夠共享Java虛擬機帶來的跨平臺性、優秀的垃圾回器,以及可靠的即時編譯器

Java技術的核心就是Java虛擬機(JVM,Java Virtual Machine),由於全部的Java程序都運行在Java虛擬機內部。

Java虛擬機就是二進制字節碼的運行環境,負責裝載字節碼到其內部,解釋/編譯爲對應平臺上的機器指令執行。每一條Java指令,Java虛擬機規範中都有詳細定義,如怎麼取操做數,怎麼處理操做數,處理結果放在哪裏。

特色:

  • 一次編譯,處處運行
  • 自動內存管理
  • 自動垃圾回收功能

2.3 JVM的位置

JVM是運行在操做系統之上的,它與硬件沒有直接的交互。

Java的體系結構:

2.4 JVM總體結構

  • HotSpot VM是目前市面上高性能虛擬機的表明做之一。
  • 它採用解釋器與即時編譯器並存的架構。
  • 在今天,Java程序的運行性能早已脫胎換骨,已經達到了能夠和C/C++程序一較高下的地步。

執行引擎包含三部分:解釋器,及時編譯器,垃圾回收器。

2.5 Java代碼執行流程

只是能生成被Java虛擬機所能解釋的字節碼文件,那麼理論上就能夠本身設計一套代碼了

2.6 JVM的架構模型

Java編譯器輸入的指令流基本上是一種基於棧的指令集架構,另一種指令集架構則是基於寄存器的指令集架構。

這兩種架構之間的區別:

基於棧式架構的特色

  • 設計和實現更簡單,適用於資源受限的系統;
  • 避開了寄存器的分配難題:使用零地址指令方式分配。
  • 指令流中的指令大部分是零地址指令,其執行過程依賴於操做棧。指令集更小,編譯器容易實現。
  • 不須要硬件支持,可移植性更好,更好實現跨平臺。

基於寄存器架構的特色

  • 典型的應用是x86的二進制指令集:好比傳統的PC以及Android的Davlik虛擬機。
  • 指令集架構則徹底依賴硬件,可移植性差
  • 性能優秀和執行更高效
  • 花費更少的指令去完成一項操做。
  • 在大部分狀況下,基於寄存器架構的指令集每每都以一地址指令、二地址指令和三地址指令爲主,而基於棧式架構的指令集倒是以零地址指令爲主。

舉例1

一樣執行2+3這種邏輯操做,其指令分別以下:

基於棧的計算流程(以Java虛擬機爲例):

0: iconst_2 // 常量2入棧
1: istore_1
2: iconst_3 // 常量3入棧
3: istore_2
4: iload_1
5: iload_2
6: iadd // 常量2/3出棧,執行相加
7: istore_3 // 結果5入棧
8: return

而基於寄存器的計算流程:

mov eax,2 //將eax寄存器的值設爲1
add eax,3 //使eax寄存器的值加3

字節碼反編譯

咱們編寫一個簡單的代碼,而後查看一下字節碼的反編譯後的結果:

public class StackStruTest {
    public static void main(String[] args) {
        int i = 2 + 3;
    }
}

而後咱們找到編譯後的 class文件,使用下列命令進行反編譯:

javap -v StackStruTest.class

獲得的文件爲:

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=2, args_size=1
         0: iconst_5
         1: istore_1
         2: return
      LineNumberTable:
        line 10: 0
        line 14: 2
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       3     0  args   [Ljava/lang/String;
            2       1     1     i   I

假若代碼爲:

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

咱們找到編譯後的 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 11: 0
        line 12: 2
        line 13: 4
        line 14: 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架構不一樣,因此不能設計爲基於寄存器的。

棧的特色:

  • 跨平臺性
  • 指令集小
  • 指令多
  • 執行性能比寄存器差

3、JVM生命週期

3.1 虛擬機的啓動

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

3.2 虛擬機的執行

  • 一個運行中的Java虛擬機有着一個清晰的任務:執行Java程序。
  • 程序開始執行時他才運行,程序結束時他就中止。
  • 執行一個所謂的Java程序的時候,真真正正在執行的是一個Java虛擬機的進程

3.3 虛擬機的退出

有以下的幾種狀況:

  • 程序正常執行結束
  • 程序在執行過程當中遇到了異常或錯誤而異常終止
  • 因爲操做系統用現錯誤而致使Java虛擬機進程終止
  • 某線程調用Runtime類或system類的exit方法,或Runtime類的halt方法,而且Java安全管理器也容許此次exit或halt操做。
  • 除此以外,JNI(Java Native Interface)規範描述了用JNI Invocation API來加載或卸載 Java虛擬機時,Java虛擬機的退出狀況。

4、JVM虛擬機分類

4.1 HotSpot VM

HotSpot歷史最初由一家名爲「Longview Technologies」的小公司設計。1997年,此公司被sun收購;2009年,Sun公司被甲骨文收購。

在JDK1.3版本時,HotSpot VM就成爲默認虛擬機。

目前Hotspot佔有絕對的市場地位,是絕對的主流

  • 無論是如今仍在普遍使用的JDK6,仍是使用比例較多的JDK8中,默認的虛擬機都是HotSpot。
  • Sun/Oracle JDK和openJDK的默認虛擬機。
  • 從服務器、桌面到移動端、嵌入式都有應用。

HotSpot指的就是它的熱點代碼探測技術。

  • 經過計數器找到最具編譯價值代碼,觸發即時編譯或棧上替換。
  • 經過編譯器與解釋器協同工做,在最優化的程序響應時間與最佳執行性能中取得平衡。

4.2 JRockit

JRockit專一於服務器端應用。

  • 它能夠不太關注程序啓動速度,所以JRockit內部不包含解析器實現,所有代碼都靠即時編譯器編譯後執行。

大量的行業基準測試顯示,JRockit JVM是世界上最快的JVM。

  • 使用JRockit產品,客戶已經體驗到了顯著的性能提升(一些超過了70%)和硬件成本的減小(達50%)。

優點:全面的Java運行時解決方案組合。

  • JRockit面向延遲敏感型應用的解決方案JRockit Real Time提供以毫秒或微秒級的JVM響應時間,適合財務、軍事指揮、電信網絡的須要。
  • MissionControl服務套件,它是一組以極低的開銷來監控、管理和分析生產環境中的應用程序的工具。

2008年,JRockit被Oracle收購。

Oracle表達了整合兩大優秀虛擬機的工做,大體在JDK8中完成。整合的方式是在HotSpot的基礎上,移植JRockit的優秀特性。

4.3 IBM的J9

全稱:IBM Technology for Java Virtual Machine,簡稱IT4J,內部代號:J9。

市場定位與HotSpot接近,服務器端、桌面應用、嵌入式等多用途VM普遍用於IBM的各類Java產品。

目前,有影響力的三大商用虛擬機之一,也號稱是世界上最快的Java虛擬機。

2017年左右,IBM發佈了開源J9VM,命名爲openJ9,交給EClipse基金會管理,也稱爲Eclipse OpenJ9。

4.4 Azul VM

前面三大「高性能Java虛擬機」使用在通用硬件平臺上這裏Azu1VW和BEALiquid VM是與特定硬件平臺綁定、軟硬件配合的專有虛擬機I

  • 高性能Java虛擬機中的戰鬥機。

Azul VM是Azu1Systems公司在HotSpot基礎上進行大量改進,運行於Azul Systems公司的專有硬件Vega系統上的ava虛擬機。

每一個Azu1VM實例均可以管理至少數十個CPU和數百GB內存的硬件資源,並提供在巨大內存範圍內實現可控的GC時間的垃圾收集器、專有硬件優化的線程調度等優秀特性。

2010年,AzulSystems公司開始從硬件轉向軟件,發佈了本身的zing JVM,能夠在通用x86平臺上提供接近於Vega系統的特性。

4.5 KVM和CDC / CLDC Hotspot

Oracle在Java ME產品線上的兩款虛擬機爲:CDC/CLDC HotSpot Implementation VM KVM(Kilobyte)是CLDC-HI早期產品目前移動領域地位尷尬,智能機被Angroid和IOS二分天下。

KVM簡單、輕量、高度可移植,面向更低端的設備上還維持本身的一片市場。

  • 智能控制器、傳感器
  • 老人手機、經濟欠發達地區的功能手機

4.6 Sun Classic VM

早在1996年Java1.0版本的時候,Sun公司發佈了一款名爲sun classic VM的Java虛擬機,它同時也是世界上第一款商用Java虛擬機,JDK1.4時徹底被淘汰。

這款虛擬機內部只提供解釋器。如今還有及時編譯器,所以效率比較低,而及時編譯器會把熱點代碼緩存起來,那麼之後使用熱點代碼的時候,效率就比較高。

若是使用JIT編譯器,就須要進行外掛。可是一旦使用了JIT編譯器,JIT就會接管虛擬機的執行系統。解釋器就再也不工做。解釋器和編譯器不能配合工做。

如今hotspot內置了此虛擬機。

4.7 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。

4.8 Taobao VM

由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官方VM版本所有替換了。

4.9 Dalvik VM

谷歌開發的,應用於Android系統,並在Android2.2中提供了JIT,發展迅猛。

Dalvik y只能稱做虛擬機,而不能稱做「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。

4.10 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工具集快速構建面向一種新語言的解釋器。在運行時還能進行即時編譯優化,得到比原生編譯器更優秀的執行效率。

總結

具體JVM的內存結構,其實取決於其實現。不一樣廠商的JVM,或者同一廠商發佈的不一樣版本,都有可能存在必定差別。咱們學習及開發都主要以Oracle HotSpot VM爲默認虛擬機。

相關文章
相關標籤/搜索