1. 程式人生 > >深入理解JVM虛擬機器開篇:JVM介紹與知識脈絡梳理

深入理解JVM虛擬機器開篇:JVM介紹與知識脈絡梳理

微信公眾號【Java技術江湖】一位阿里 Java 工程師的技術小站。作者黃小斜,專注 Java 相關技術:SSM、SpringBoot、MySQL、分散式、中介軟體、叢集、Linux、網路、多執行緒,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!(關注公眾號後回覆”Java“即可領取 Java基礎、進階、專案和架構師等免費學習資料,更有資料庫、分散式、微服務等熱門技術學習視訊,內容豐富,兼顧原理和實踐,另外也將贈送作者原創的Java學習指南、Java程式設計師面試指南等乾貨資源)

 

                     

 

轉自:https://mp.weixin.qq.com/s/EjVfk1iOuQUjLfPxt_DJ7Q

 

是大名鼎鼎的Java 虛擬機器,  據說這個星球上每天有900多萬程式設計師和我打交道,這真是一個驚人的數字。 這900多萬人中不少人對我的技術內幕非常感興趣, 有事兒沒事兒都要把我“大卸八塊”, 深入瞭解一下。甚至還有人從我的出生地--原始碼--開始看起,弄得人家連一點隱私都沒有了。

 

當然也有很多人對我的執行機理愛理不理, 理由很簡單: Java虛擬機器相關的事情只有在面試時才會問道,背誦一下那些垃圾回收演算法,應付過去就可以了!

 

真的是這樣嗎?  面試官為什麼喜歡問JVM原理? 難道他們沒什麼可問的了? 或者是隻是為了展示他們的卓爾不群? 高人一等?壓你一頭?

 

我想都不是,  請注意一下我的名字: Java虛擬機器,  我是一個虛擬機器啊!

 

雖然不是像VMWare, VirtualBox那樣可以完全虛擬出一個包括記憶體,硬碟,CPU的硬體計算機出來, 我至少也是個Soft CPU啊, 有自己的指令集,有自己獨有的可執行檔案格式, 有自己獨特的基於棧而不是暫存器的執行方式,還有那久經考驗的垃圾回收機制......

 

作為一個口口聲聲說熱愛程式設計,立志有寫出偉大軟體來改變世界的程式設計師, 少年, 難道你竟然對這麼有趣的東西視而不見?

 

對軟體技術的好奇心是你最終成為偉大程式設計師的第一驅動力, 如果你對技術不願意深究, 不願意瞭解背後的原理,如果你不願意像一個調皮搗蛋的熊孩子那樣把一個玩具變成零件,然後再組裝起來(嗯, 實際上永遠都組裝不起來了) , 我真的懷疑你在這個行業能呆多久,走多遠。

 

我剛才提到了有趣, 那真的有用嗎?

 

表面上看是沒有用處的,至少短期看來是沒有用處的, 你寫程式,執行程式,然後吃飯,睡覺。

 

管你什麼基於棧的虛擬機器,什麼方法區,堆, 垃圾回收,  生活很美好,世界也很大, 我想去看看, 不要用這些煩心事來煩我。

如果你想一直生活在軟體開發的表層, 那肯定是沒有問題的, 如果你想像Neo那樣,把這個世界看個清清楚楚,明明白白,真真切切, 就需要修煉一下內力, 做為Java 程式設計師, 理解Java虛擬機器就是那個扎馬步的基本功。

 

舉個例子, 理解Class 檔案格式, 就能理解ASM是怎麼在執行時“艱難的”動態生成位元組碼的, 然後就會知道CGLib是怎麼改善它, 讓它容易使用的。  而CGLib可是Spring AOP賴以生存的一大基礎啊。 這一路走來,是不是對AOP的理解更加透徹了?

 

你腦海中甚至能想象出來位元組碼怎麼被動態的建立,被Classloader 載入, 形成新的Class,   然後對你的業務類進行攔截的過程。

看透世界的感覺不要太爽,    如果你非要說我會用Spring 的AOP就行了, 那我也沒辦法, 人各有志嘛。

 

擴充套件一下, 現在我的家中上入住了不少動態語言, Jython, JRuby , Clojure , Scala 等等, 他們可都需要動態的生成位元組碼來執行啊(碼農翻身備註: Scala 也可以直接編譯成class 檔案), 你看看理解了Class 檔案格式得有多大的好處。

 

還有啊, 理解了一些重要的位元組碼指令以後,你就會知道所謂的面向物件, 尤其是你寫的那些個漂亮的OO程式碼, 在我這裡已經“退化”成函式呼叫了, 不知道你會不會沮喪, 但是沒有辦法, 咱們計算機的本質就是這樣,順序,迴圈,分支, 函式呼叫。 作為補償, 我會讓你瞭解多型的祕密, 這可是很多面向物件語言的基礎。

 

說到函式呼叫, 你寫的Java程式在執行時會形成的棧幀, 這可真是一個超級重要的概念, 不僅在我這裡有,物理CPU和記憶體在執行原生代碼的時候也有,雖然我和他們的結構不同, 但都是為了完成一個目的:  表達一個函式在執行時的結構。

 

瞭解了這個傢伙, 你就知道函式在機器級是怎麼呼叫的, 引數是怎麼傳遞的, 遞迴是怎麼回事, 尾遞迴是怎麼回事(我竟然不支援!) 。  也許你會跑去看看彙編, 去看看緩衝區溢位攻擊, 各種知識點開始連線,形成一張大網,這種感覺是極爽的。

 

這樣的例子我還可以舉出很多,但是估計很多人已經不耐煩了,就此打住。

 

你們人類說計算機是門科學, 但是科學的成分在哪裡呢?  在我看來更像一門工程或者技術,  核心的基礎概念真的不多, 花點功夫把他們掌握了,受益終生。

 

前些天我偷偷地閱讀了你們的小說《天龍八部》, 裡邊的掃地僧可真是厲害, 輕輕鬆鬆就把慕容博和蕭遠山兩位絕頂高手製得服服帖帖,老老實實, 這說明的什麼問題? 內功的修煉真是很重要啊。

 

jvm.png

前言

 JVM(Java Virtual Machine)Java 虛擬機器是整個 java 平臺的基石,是 java 系統實現硬體無關與作業系統無關的關鍵部分,是保障使用者機器免於惡意程式碼損害的屏障。Java開發人員不需要了解JVM是如何工作的,**但是,**瞭解 JVM 有助於我們更好的開(通)發(過) java(公司) 程(面)序(試)。

寫這篇文章的目的:

  • 總結所學的 JVM 知識
  • 幫助想了解 JVM 的朋友,知無不言,言無不盡

本篇文章將會介紹一下內容:

  • 什麼是 JVM
  • JVM 用來做什麼事情
  • JVM 生命週期
  • JVM 的整體架構
  • JVM 記憶體管理
  • 總結

什麼是 JVM

要想說明白什麼 JVM 就不得不提另外兩個概念,JRE 和 JDK,初學者總是把這幾個概念搞混

java-tutorial.png

 

Jvm,Jre,Jdk 都是 java 語言的支柱,他們分工協作。但不同的是 Jdk 和 Jre 是真實存在的,而 Jvm 是一個抽象的概念,並不真實存在。

JDK
JDK(Java Development Kit) 是 Java 語言的軟體開發工具包(SDK)。JDK 物理存在,是 programming tools、JRE 和 JVM 的一個集合

jdk.png


JRE
JRE(Java Runtime Environment)Java 執行時環境,JRE 物理存在,主要由Java API 和 JVM 組成,提供了用於執行 java 應用程式最低要求的環境。

jre.png

 

JVM
JVM(Java Virtual Machine) 是一種軟體實現,執行像物理機程式的機器(即電腦)。
本來,Java被設計基於從物理機器分離實現WORA( 寫一次,隨處執行 )的虛擬機器上執行,雖然這個目標已經幾乎被遺忘。
JVM 並不是專為 Java 所實現的執行時,實際上只要有其他程式語言的編譯器能生成正確 Java bytecode 檔案,則這個語言也能實現在JVM上執行。
因此,JVM 通過執行 Java bytecode 可以使 java 程式碼在不改變的情況下執行在各種硬體之上。
jVM 有如下特點:

  • 基於堆疊的虛擬機器 :最流行的計算機體系結構,如英特爾X86架構和ARM架構上執行基於暫存器 。 但是,JVM是基於棧的。
  • 符號引用 :除了基本型別以外的資料(類和介面)都是通過符號來引用,而不是通過顯式地使用記憶體地址來引用。
  • 垃圾收集 :一個類的例項是由使用者明確建立的程式碼和垃圾回收自動銷燬。
    通過明確界定的基本資料型別的保證平臺的獨立性 :傳統的語言,如C / C ++根據平臺有不同的int型的大小。 JVM中明確規定了基本資料型別,以保持它的相容性和保證平臺的獨立性。
  • 網路位元組順序 :Java class檔案用網路位元組碼順序來進行儲存:為了保證和小端的Intel x86架構以及大端的RISC系列的架構保持無關性,JVM使用用於網路傳輸的網路位元組順序,也就是大端。

**Java bytecode **
為了實現WORA,JVM使用Java位元組碼,java(使用者語言)和機器語言之間的中間語言。
該Java位元組碼是部署Java程式碼的最小單位。

JVM 用來做什麼

基於安全方面考慮,JVM 要求在 class 檔案中使用許多強制性的語法和機構化約束,但任意一門功能性語言都可以表示為一個能被 JVM 接受的有效的 class 檔案。作為一個通用的、機器無關的執行平臺,任何其他語言的實現者都可將 JVM 當作他的語言產品交付媒介。

JVM 中執行以下操作:

  • 載入程式碼
  • 驗證程式碼
  • 執行程式碼
  • 提供執行環境

JVM 提供定義了:

  • 儲存區
  • 類檔案格式
  • 暫存器組
  • 垃圾回收堆
  • 致命錯誤報告等

JVM 生命週期

  • 啟動:任何一個擁有main函式的class都可以作為JVM例項執行的起點
  • 執行:main函式為起點,程式中的其他執行緒均有它啟動,包括daemon守護執行緒和non-daemon普通執行緒。daemon是JVM自己使用的執行緒比如GC執行緒,main方法的初始執行緒是non-daemon。
  • 消亡:所有執行緒終止時,JVM例項結束生命。

JVM 的整體架構

先看一下 java 程式碼執行過程

關於Jvm知識看這一篇就夠了

轉自: 純潔的微笑 純潔的微笑 3月11日

2016年左右的時候讀了周志明《深入理解Java虛擬機器:JVM高階特性與最佳實踐》,讀完之後受益匪淺,讓我對Java虛擬機器有了一個完整的認識,這是Jvm書籍中最好的讀物之一。

 

後來結合實際工作中遇到的問題,寫了一系列關於Jvm的文章,其中開篇的幾篇內容大部分參考於此書,後期加入自己一些實戰的理解,轉載了幾篇高質量的文章,就形成了此係列讀物。

 

 

 

在金三銀四的跳槽季中,很多小夥伴們都已經蠢蠢欲動,將此係列文章整理出來,希望可以幫助到大家。

 

  • Jvm系列(一):java類的載入機制

 

 

第一篇文章講的是Java類的載入機制,也是我在部落格園最收歡迎的Jvm文章,讀完之後你會了解什麼是類載入器、類載入機制、雙親委派模型等內容。

 

  • Jvm系列(二):JVM記憶體結構

     

 

這篇文章描述了Java虛擬機器的記憶體結構,記憶體每個區域作用,如何通過引數對各個區域進行控制。

 

  • Jvm系列(三):GC演算法  垃圾收集器

 

講述了Jvm垃圾回收的經典演算法,以及各種垃圾回收機制,物件存活判斷等。

 

  • Jvm系列(四):jvm調優-命令篇

這篇文章講述瞭如何通過Jvm命令去調優,各Jvm命令使用方法。

 

  • Jvm系列(五):Java GC分析

 

這是非常有名的一張圖,簡單明瞭展示了GC日誌的構成

文章介紹如何分析GC日誌來診斷Java專案的執行狀態,GC分析是生產調優的重要手段之一。

 

  • Jvm系列(六):Java服務GC引數調優案例

一名網友根據GC日誌,進行Jvm調優的經典案例

 

  • Jvm系列(七):jvm調優-工具篇

介紹了Jvm調優各種工具的使用

 

  • Jvm系列(八):jvm知識點總覽

如何你只是想通過面試,其實只要看一篇就夠了,這篇文章將Jvm中的關鍵知識點進行了彙總。

 

  • Jvm系列(九):如何優化Java GC

翻譯自國外的一篇Java GC文章,文章詳細描述幾種GC調優的方式,值得借鑑。

 

  • Jvm系列(十):教你如何成為Java的OOM Killer

也是線上一場線上Jvm實戰調優的經歷,看著挺爽。

 

  • Jvm系列(十一):Java 8-從持久代到metaspace

Java 8 Jvm記憶體變化

 

  • Jvm系列(十二):Java 8的新特性—終極版

杜琪翻譯的 Java 8 的新特性。

 

  • 一個指令碼引發的血案

我們曾經線上出現事故後,定位分析的經歷,結局出乎意料。