【JVM學習】jvm與java的體系結構

你是否也遇到過這些問題?

●運行着的線上系統突然卡死,系統無法訪問,甚至直接0OM!
●想解決線上JVM GC問題,但卻無從下手。
●新項目上線,對各種JVM參數設置- -臉茫然, 直接默認吧,然後就JJ了
●每次面試之前都要重新背一.遍JVM的一些原理概念性的東西,然而面試官卻經常問你在實際項目中如何調優JVM參數,如何解決GC、00M等問題,一臉懵逼。

在這裏插入圖片描述
大部分Java開發人員,除會在項目中使用到與Java平臺相關的各種高精尖技術,對於Java技術的核心Java虛擬機瞭解甚少。

開發人員如何看待上層框架

● 一些有一定工作經驗的開發人員,打心眼兒裏覺得SSM、微服務等上層技術纔是重點,基礎技術並不重要,這其實是一種本末倒置的“病態”
●如果我們把核心類庫的API比做數學公式的話,那麼Java虛擬機的知識就好比公式的推導過程。

在這裏插入圖片描述
計算機系統體系對我們來說越來越遠,在不瞭解底層實現方式的前提下,通過高級語言很容易編寫程序代碼。但事實上計算機並不認識高級語言

我們爲什麼要學習JVM ?

  • 面試的需要(BATJ、 TMD、 PKQ等面試都愛問)
  • 中高級程序員必備技能,
    – 項目管理、調優的需要
  • 追求極客的精神
    – 比如: 垃圾回收算法、 JIT、底層原理

在這裏插入圖片描述
垃圾收集機制爲我們打理了很多繁瑣的工作,大大提高了開發的效率,但是,垃圾收集也不是萬能的,懂得JVM內部的內存結構、工作機制,是設計高擴展性應用和診斷運行時問題的基礎,也是Java工程師進階的必備能力。

在這裏插入圖片描述

跨語言的平臺:JVM

在這裏插入圖片描述
● 隨着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爲核心的一 系列項目和功能改進( 如DaVinci Machine項目、 Nashorn引擎、InvokeDynamic指令、java. lang. invoke包等),推動Java虛擬機從“Java語言的虛擬機”向“多語言虛擬機”的方向發展。

Java發展的重大事件

  • 1990年,在Sun計算機公司中,由Patrick Naughton、 Mi keSheridan及James Gosling 領導的小組Green Team, 開發出的新的程序語言,命名爲0ak,後期命名爲Java
  • 1995年,Sun正式發佈Java和HotJava產品,Java首次公開亮相。
  • 1996年1月23日Sun Microsystems發佈了JDK 1.0。
  • 1998年,JDK 1.2版本發佈。同時,Sun發佈了JSP/Servlet、 EJB規範,以及將Java分成了J2EE、 J2SE和J2ME。這表明 了Java開始向 企業、桌面應用和移動設備應用3大領域挺進。
  • 2000年,JDK 1.3發佈,Java HotSpot Virtual Machine正式發佈,成爲Java的默認虛擬機。
  • 2002年,JDK 1.4發佈,古老的Classic虛擬機退出歷史舞臺。
  • 2003年年底,Java平臺的Scala正式發佈,同年Groovy也加入了Java陣營。
  • 2004年, JDK 1.5發佈。同時JDK 1.5改名爲JavaSE 5.0。
  • 2006年,JDK 6發佈。同年,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發佈。在JDK 1.7u4中,正式啓用了新的垃圾回收器G1。
  • 2017年,JDK9發佈。將G1設置爲默認GC,替代CMS,同年,IBM的J9開源,形成了現在的0pen J9社區
  • 2018年, Android的Java侵權案判決,Goog1e賠償Orac1e計88億美元,同年,Oracle宣告JavaEE成爲歷史名詞,JDBC、 JMS、Servlet贈予Eclipse基金會,同年,JDK11發佈,LTS版本的JDK,發佈革命性的ZGC,調整JDK授權許可
  • 2019年,JDK12發佈,加入RedHat領導開發的Shenandoah GC

虛擬機

  • 所謂虛擬機 (Virtual Machine),就是一臺虛擬的計算機。 它是一款軟件,用來執行一系列虛擬計算機指令。大體上,虛擬機可以分爲系統虛擬機和程序虛擬機。
    –> 大名鼎鼎的Visual Box, VMware就屬於系統虛擬機,它們完全是對物理計算機的仿真,提供了一個可運行完整操作系統的軟件平臺。
    –> 程序虛擬機的典型代表就是Java虛擬機,它專門爲執行單個計算機程序而設計,在Java虛擬機中執行的指令我們稱爲Java字節碼指令。
  • 無論是 系統虛擬機還是 程序虛擬機,在上面運 行的軟件都被限制於虛擬機提供的資源中。

Java虛擬機

  • Java虛擬機是一臺執行Java字節碼的虛擬計算機,它擁有獨立的運行機制,其運行的Java字節碼也未必由Java語言編譯而成。
  • JVM平臺的各種語言可以共享Java虛擬機帶來的跨平臺性、優秀的垃圾回器,以及可靠的即時編譯器。
  • Java技術的核心就是Java虛擬機(JVM,Java Virtual Machine) ,因爲所有的Java程序都運行在Java虛擬機內部。

Java虛擬機作用

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

特點

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

JVM的位置

在這裏插入圖片描述
JVM是運行在操作系統之上的,它與硬件沒有直接的交互。

在這裏插入圖片描述

JVM的整體結構

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

在這裏插入圖片描述

Java代碼執行流程

在這裏插入圖片描述

  • Java編譯器編譯過程中,任何一個節點執行失敗就會造成編譯失敗。
  • 雖然各個平臺的Java虛擬機內部實現細節不盡相同,但是它們共同執行的字節碼內容卻是- -樣的。
  • JVM的主要任務就是負貴將字節碼裝載到其內部,解釋/編譯爲對應平臺,上的機器指令(即:彙編語言)執行。
  • Java虛擬機使用類加載器(Class Loader)裝載class 文件。
  • 類加載完成之後,會進行字節碼校驗,字節碼校驗通過之後JVM解釋器會把字節碼翻譯成機器碼(即:彙編語言)交由操作系統執行。
  • 但不是所有代碼都是解釋執行的,JVM對此做了優化。比如,以Hotspot虛擬機來說,它本身提供了JIT (Just In Time)

JVM的架構模型

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

  • 基於棧式架構的特點
    ➢設計和實現更簡單,適用於資源受限的系統;
    ➢避開了寄存器的分配難題:使用零地址指令方式分配。
    ➢指令流中的指令大部分是零地址指令,其執行過程依賴於操作棧。指令集更小編譯器容易實現。
    ➢不需要硬件支持,可移植性更好,更好實現跨平臺
  • 基於寄存器架構的特點
    ➢典型的應用是x86的二進制指令集:比如傳統的PC以及Android的Davlik虛擬機。
    ➢指令集架構則完全依賴硬件,可移植性差
    ➢性能優秀和執行更高效;
    ➢花費更少的指令去完成一-項操作。
    ➢在大部分情況下,基於寄存器架構的指令集往往都以一地址指令、二地址指令和三地址指令爲主,而基於棧式架構的指令集卻是以零地址指令爲主。

在這裏插入圖片描述
總結:
由於跨平臺性的設計,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虛擬機的退出情況。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章