一篇文章瞭解Java虛擬機

1、概述

一、簡要了解java的技術體系

  • Java程序設計語言
  • JVM
  • Clas文件格式
  • JavaApi類庫

java技術體系.jpeg

二、Java的運行機制

java運行機制.png
Java編寫的程序經過Java編譯器編譯成Java字節碼(class文件),Java虛擬機載入字節碼, 解釋運行程序。

三、什麼是Java虛擬機

Java虛擬機(Java Virtual Machine 簡稱JVM) 是運行全部Java程序的抽象計算機,是Java語言的運行環境。
Java虛擬機有本身完善的硬體架構,如處理器、堆棧、寄存器等,還具備相應的指令系統。
JVM屏蔽了與具體操做系統平臺相關的信息,使得Java程序只需生成在Java虛擬機上運行的目標代碼(字節碼),就能夠在多種平臺上不加修改地運行。java

2、JVM結構

JVM結構圖.png

一、類加載器(ClassLoader)

類的裝載.png
是Java運行時環境(Java Runtime Environment)的一部分,負責動態加載Java類到Java虛擬機的內存空間中。 (1) 裝載:查找和導入Class文件; (2) 連接:把類的二進制數據合併到JRE中;

  • 校驗:檢查載入Class文件數據的正確性;
  • 準備:給類的靜態變量分配存儲空間;
  • 解析:將符號引用轉成直接引用;

(3) 初始化:對類的靜態變量,靜態代碼塊執行初始化操做 (4) 使用: 類的使用 (5) 卸載: 生命週期結束算法

二、執行引擎

負責執行class文件中包含的字節碼指令架構

三、本地方法接口

主要是調用C或C++實現的本地方法及返回結果併發

四、運行時數據區

運行時數據區.png

方法區

  • 用於存放已被虛擬機加載的類信息、常量、靜態變量、編譯後的代碼等數據。
  • 各個線程共享的存儲區域
  • 熟悉HotSpot虛擬機的開發人員稱之爲"永久代",本質上二者並不相等
  • 雖然JVM規範把方法區描述爲堆的一個邏輯部分, 但它卻有個別名non-heap(非堆),目的在於與Heap區分開來

  • 用於存放對象實例,幾乎全部對象實例都在這裏分配內存
  • JVM中內存最大的一塊
  • 全部線程共享的內存區域
  • 垃圾收集器管理的主要區域
  • 可細分爲新生代和老年代

虛擬機棧

  • 每運行一個方法就建立一個棧幀,用於存儲局部變量表、操做棧、方法返回值等。
  • java棧老是和線程關聯在一塊兒,每當建立一個線程時,JVM就會爲這個線程建立一個對應的java棧
  • 線程私有, 生命週期與線程相同
  • 每個方法從調用直至執行完成的過程,就對應一個棧幀在java棧中入棧到出棧的過程

本地方法棧

  • 與虛擬機棧做用類似, 區別在於本地方法棧使用到的是Native方法服務

程序計數器

  • 是一塊較小的內存空間,做用是當前線程所執行的字節碼的行號指示器
  • 字節碼解釋器工做時經過改變計數器的值選取下條須要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等功能所須要依賴計數器完成
  • 爲避免線程間計數器的互相影響,每一個線程都須要有一個獨立的程序計數器

3、垃圾回收(GC)

垃圾回收主要有兩個步驟:學習

  • 垃圾判斷: 檢索哪些對象是可回收的垃圾
  • 垃圾回收: 對檢測出的垃圾進行銷燬回收, 騰出空間供新對象生成

一、垃圾判斷算法

引用計數算法

  • 原理: 對每個對象都提供一個關聯的引用計數,以此來標識該對象是否被使用, 當這個計數爲0時, 說明這個對象已經再也不被使用了。
  • 優勢: 算法簡單; 而且不用暫停引用, 當計數變爲0時, 便可將此的對象的內存空間回收
  • 缺點: 沒法解決循環引用問題

可達性分析算法

以根集對象爲起始點進行搜索,若是有對象不可達的話,便是垃圾對象。這裏的根集通常包括java棧中引用的對象、方法區常良池中引用的對象,本地方法中引用的對象等。優化

二、垃圾回收算法

標記-清除算法(Mark-Swap)

標記-清除算法.png
此算法執行分兩階段。第一階段從引用根節點開始標記全部被引用的對象,第二階段遍歷整個堆,把未標記的對象清除。此算法須要暫停整個應用,同時,會產生內存碎片。

標記-整理算法(Mark-Compact)

標記整理算法.png
標記整理算法相似與標記清除算法,不過它標記完對象後,不是直接對可回收對象進行清理,而是讓全部存活的對象都向一端移動,而後直接清理掉邊界之外的內存。

複製算法(Copying)

複製算法.png
此算法把內存空間劃爲兩個相等的區域,每次只使用其中一個區域。
垃圾回收時,遍歷當前使用區域,把正在使用中的對象複製到另一個區域中。
此算法每次只處理正在使用中的對象,所以複製成本比較小,同時複製過去之後還能進行相應的內存整理,不會出現「碎片」問題。固然,此算法的缺點也是很明顯的,就是須要兩倍內存空間

分代算法(Generational)

分代算法.png

  • 當前商業虛擬的垃圾算法都採用該算法。
  • 根據對象存活週期的不一樣將內存劃分爲多塊(例如:新生代、老年代),根據各個塊的特色制定相應的回收策略。
  • 新生代中每次收集時都有大部分對象四驅, 只存活少數, 通常採用複製算法
  • 老年代存活率高, 通常採用「標記-整理」或「標記-清除」算法

三、HotSpot JVM的分代垃圾清理

上述講解如何區分垃圾,以及垃圾是如何回收的, 如今咱們來看看HotSpot JVM是如何實現垃圾回收的。 網站

HotSpotJVM分代算法.png

  • 按照對象存活劃分紅: 新生代、老年代、持久帶
  • 新生代分位一個Eden區和兩個Survivor區,每次使用一個Eden區和一個Survivor區。默認Eden區與Survivor區的大小比例爲8:1
  • 回收時將Eden區和Survivor區中還存活的對象拷貝到另外一個Survivor區,清理掉Eden區和剛使用過多的Survivor區中的空間。

四、垃圾收集器

若是說垃圾收集算法是方法論, 那麼垃圾收集器就是內存回收的具體實現。操作系統

常見的垃圾收集器

垃圾收集器 適用區 類別 算法 使用場景
Serial 新生代 串行 複製算法 單CPU環境下的Client模式
ParNew 新生代 並行 複製算法 多CPU環境時在Server模式下與CMS配合
Parallell Scavenge 新生代 並行 複製算法 在後臺運算而不須要太多交互的任務
CMS 老年代 併發 標記-清除算法 集中在互聯網站或B/S系統服務端上的Java應用
Serial Old 老年代 串行 標記-整理算法 單CPU環境下的Client模式、CMS的後備預案
Parallel Old 老年代 並行 標記-整理算法 在後臺運算而不須要太多交互的任務
G1 新年代與老年代 並行與併發 標記-整理算法 面向服務端應用,未來替換CMS

其中:線程

  • 並行(parallel): 指多個收集器的線程同時工做, 但用戶線程處於等待狀態。
  • 併發(concurrent): 指收集器在工做的同時, 能夠容許用戶線程工做。
  • 並行收集器: 吞吐量優化的收集器。
  • 併發收集器: 暫停時間優化的收集器。

垃圾收集器的使用

垃圾收集器使用.jpg
上圖展現了7種做用於不一樣分代的收集器,若是兩個收集器之間存在連線,就說明它們能夠搭配使用。
虛擬機所處的區域,則表示它是屬於新生代收集器仍是老年代收集器。
Hotspot實現瞭如此多的收集器,正是由於目前並沒有完美的收集器出現,只是選擇對具體應用最適合的收集器

4、總結

本片文章比較簡單介紹了Java虛擬機, 相信對你們對Java虛擬機有了必定的瞭解。
固然文中不少方面都沒進行深刻講解,若是想更深入的瞭解原理能夠自行購買相關書籍或者網上搜索相關內容進行學習。
推薦學習書籍《深刻理解Java虛擬機-JVM高級特性與最佳實踐》設計


參考資料:

  • 《深刻理解Java虛擬機-JVM高級特性與最佳實踐》
  • 《Java虛擬機規範(第二版)》
  • 《IBM JVM Garbage Collection And Storage Allocation techniques》

喜歡能夠關注公衆號: 終身幼稚園

終身幼稚園
相關文章
相關標籤/搜索