HotSpot實戰

《HotSpot實戰》是人民郵電出版社2014年出版的書籍,作者是陳濤。HotSpot是一款高性能的Java虛擬機,可以大大提高Java運行的性能。Java原先是把原始碼編譯為位元組碼在虛擬機執行,這樣整體執行效率不高。而HotSpot關注的是對部分熱點(hot spot)代碼的動態最佳化,將那些頻繁執行的熱點代碼編譯為本地原生代碼,這樣就顯著地提高了性能。

內容簡介

每個Java開發者都知道Java位元組碼是在JRE上執行的。JRE中最重要的部分就是Java虛擬機(JVM),JVM負責分析和執行Java位元組碼。通常情況下,Java開發人員並不需要去關心JVM是如何運行的。即使不理解JVM的工作原理,也不會給開發人員帶來過多困惑。不過,如果你了解JVM的話,就會更加了解Java,並且能夠解決很多看似棘手的問題。

很多開發工程師不願意花時間去了解JVM的底層,因為了解的過程很辛苦,也很枯燥。陳濤喜歡專研技術,他不僅對Java、C、C++熟悉,而且對作業系統底層也很熟悉。他的知識面也比較廣,能夠將理論很好地套用於實踐中。《HotSpot實戰》便是他潛心研究和實踐的成果。

本書第一次系統全面地剖析了具體的虛擬機產品(即HotSpot,Oracle官方虛擬機)的實現,填補了市場上這類圖書的空白。作者不僅透徹地講解了那些看似深奧的原理,還提供了很多容易上手的實踐案例。該書的一個突出特色是:讀者通過自己動手實踐便可掌握原本難以理解的原理。這為讀者學習JVM提供了一條輕鬆的途徑。此外,書中還深入淺出地介紹了很多實戰套用的方法和技巧,具有較強的現實意義。

陳濤是網易寶的核心開發人員之一,同時維護了網易寶的多個系統。網易寶是網易官方的線上支付系統,對開發工程師的技術要求極高。尤其是在邏輯上,不能有半點疏忽,因為任何錯誤都有可能導致幾百萬甚至上千萬的損失。他在不耽誤正常工作的同時能夠完成一本高質量的技術書籍,是非常不容易的。

趙 剛

網易寶系統負責人,資深技術專家

前言

在聚賢莊一役中,金庸先生描寫了一場頗有意思而又寓意深刻的較量。玄難捨棄自己的成名絕技不用,使出習武之人眾所周知的入門功夫太祖長拳與喬峰決戰。僅區區幾個回合下來,便引得群雄對玄難由衷地讚嘆:“同樣的一招入門拳法,在他手底竟有這么強大的威力”。而當喬峰也使出太祖長拳還以顏色時,眾人更是情不自禁地喝彩:“武林高手畢生所盼望達到的拳術完美之境,竟在這一招中表露無疑”。這個場面給我深刻的啟示:紮實的根基與持續的打磨,才是技術人員的修行之道。

技術能力的培養與武功的修行,同樣遵循著循序漸進的發展規律。在達到高手境界之前,每個人都需要從零起步並堅持不懈地學習。這聽起來似乎很難,畢竟我們不知道會遇到多少困難。但有一個天大的困難卻是顯而易見的,那就是技術人員自身的浮躁。

近些年來,網際網路技術猶如開足馬力的高速列車一樣,在飛速地前進著。似乎“快”一詞已經成了時下網際網路領域最貼切的寫照。為了維持市場競爭力,我們必須持續地、快速地更新自身的產品和服務。而技術人員很容易在緊迫的deadline面前忘卻了自身的技術追求。我們,正在變得浮躁起來。

為什麼會寫這本書

“蚓無爪牙之利,筋骨之強,上食埃土,下飲黃泉,用心一也。蟹六跪而二螯,非蛇蟮之穴無可寄託者,用心躁也”。對於技術人員來說,如果長期忽略自身技術的根基而去一昧地追求高層框架技術,這無疑是舍本求末的做法。

相較於C或C++程式設計師,我發現Java程式設計師更容易忽視基礎技術。JVM的出現,為程式設計師禁止了作業系統與硬體的細節,使得程式設計師從諸如記憶體管理這樣的繁瑣任務中解放出來。但這不並等同於允許Java程式設計師放棄對基礎的重視。我們是否有過這樣的經歷,在遇到記憶體故障、丟包、網路協定設計、資源瓶頸、證書、二進制等問題時,往往會覺得比較棘手,在尋求解決思路時更是顯得力不從心。這實質上是自身技術遇到了瓶頸難以突破所致。可怕的是,想去深究的時候卻無從下手。

我寫這本書的初衷是為了喚起Java程式設計師對於基礎技術的重視。事實上,任何平台的程式設計師都應當了解平台的基本特性、實現機制以及接口,這是提高自身修養的必經之路。對於Java程式設計師來說,我們需要了解的平台就是JVM。了解JVM的基本實現機制,不僅對於解決實際套用中諸如GC等虛擬機問題時有直接幫助,還有利於我們更好地理解語言本身。

所幸的是,Oracle官方已經將虛擬機項目的源碼開放出來,這對於我們來說簡直就是福音。本書將以OpenJDK和HotSpot為素材,深入淺出地講解我們最為熟悉的一款虛擬機產品的實現。除了Java程式設計師,從事與Java或JVM相關的開發、測試、運維等技術人員也將在本書中獲益。

本書內容

本書深入淺出地講解了HotSpot虛擬機的工作原理,將隱藏在它內部的本質內容逐一呈現在讀者面前,包括OpenJDK與HotSpot項目、編譯和調試HotSpot的方法、HotSpot核心結構、Launcher、OOP-Klass對象表示系統、連結、運行時數據區、方法區、常量池和常量池Cache、Perf Data、Crash分析方法、轉儲分析方法、垃圾收集器的設計演進、CMS和G1收集器、棧、JVM對硬體暫存器的利用、棧頂快取技術、解釋器、位元組碼錶、轉發表、Stubs、Code Cache、Code生成器、JIT編譯器、C1編譯器、編譯原理、JVM指令集實現、函式的分發機制、VTABLE和ITABLE、異常表、虛擬機監控工具(如jinfo、jstack、jhat、jmap等)的實現原理和開發方法、Attach機制、基於GUI的JVM分析工具(如MAT、VisualVM)等內容。

除了HotSpot技術,本書強調了對方法論的探討。在各個章節的講解中,都會有一些與系統運行機制相關的實戰或練習,供讀者練手。通過這些實戰練習,不僅有助於讀者加深對知識或原理的理解,更為重要的是,它還可以培養讀者掌握獨立探索的思維方式和運用方法,這有助於讀者把知識融會貫通並靈活套用到實際項目中。

古人云“授人以魚,不如授之以漁”,本書並不是簡單地列舉那些高深莫測的知識點,而是力求將理論與實踐有機地結合起來,培養讀者掌握獨立分析JVM底層機制的能力。讀者在今後的實踐中,可以通過自己動手實踐就能揭開HotSpot內部機制的神秘面紗,汲取到書本上沒有介紹但是實際項目中又急需的“營養”。

本書適用讀者

本書適合於已具有一定Java編程基礎的讀者,以及在Java或基於JVM的程式語言平台下進行各類軟體開發的開發人員、測試人員以及運維人員。對於JVM和程式語言愛好者來說,本書也具有一定的學習參考價值。

作品目錄

第1章 初識HotSpot

1.1 JDK概述

1.1.1 JCP與JSR

1.1.2 JDK的發展歷程

1.1.3 Java 7的語法變化

1.2 動手編譯虛擬機

1.2.1 原始碼下載

1.2.2 HotSpot原始碼結構

1.2.3 搭建編譯環境

1.2.4 編譯目標

1.2.5 編譯過程

1.2.6 編譯常見問題

1.3 實戰:在HotSpot內調試HelloWorld

1.3.1 認識GDB

1.3.2 準備調試腳本

1.4 小結

第2章 啟動

2.1 HotSpot核心

2.1.1 如何閱讀原始碼

2.1.2 HotSpot核心框架

2.1.3 Prims

2.1.4 Services

2.1.5 Runtime

2.2 啟動

2.2.1 Launcher

2.2.2 虛擬機生命周期

2.2.3 入口:main函式

2.2.4 主執行緒

2.2.5 InitializeJVM函式

2.2.6 JNI_CreateJavaVM函式

2.2.7 調用Java主方法

2.2.8 JVM退出路徑

2.3 系統初始化

2.3.1 配置OS模組

2.3.2 配置系統屬性

2.3.3 載入系統庫

2.3.4 啟動執行緒

2.3.5 vm_init_globals函式:初始化全局數據結構

2.3.6 init_globals函式:初始化全局模組

2.4 小結

第3章 類與對象

3.1 對象表示機制

3.1.1 OOP-Klass二分模型

3.1.2 Oops模組

3.1.3 OOP框架與對象訪問機制

3.1.4 Klass與instanceKlass

3.1.5 實戰:用HSDB調試HotSpot

3.2 類的狀態轉換

3.2.1 入口:Class檔案

3.2.2 類的狀態

3.2.3 載入

3.2.4 連結

3.2.5 初始化

3.2.6 實戰:類的“族譜”

3.2.7 實戰:系統字典

3.3 創建對象

3.3.1 實例對象的創建流程

3.3.2 實戰:探測JVM內部對象

3.4 小結

第4章 運行時數據區

4.1 堆

4.1.1 Java的自動記憶體管理

4.1.2 堆的管理

4.2 執行緒私有區域

4.2.1 PC

4.2.2 JVM棧

4.3 方法區

4.3.1 紐帶作用

4.3.2 常量池

4.3.3 常量池快取:ConstantPoolCache

4.3.4 方法的表示:methodOop

4.3.5 方法的解析:將符號引用轉換成直接引用

4.3.6 代碼放在哪裡:ConstMethodOop

4.3.7 實戰:探測運行時常量池

4.4 性能監控數據區:Perf Data

4.4.1 描述這段空間:PerfMemory

4.4.2 查看

4.4.3 生產

4.5 轉儲

4.5.1 用VisualVM進行轉儲分析

4.5.2 JVM Crash

4.6 小結

第5章 垃圾收集

5.1 堆與GC

5.1.1 垃圾收集

5.1.2 分代收集

5.1.3 快速分配

5.1.4 棧上分配和逸出分析

5.1.5 GC公共模組

5.2 垃圾收集器

5.2.1 設計演進

5.2.2 CMS收集器

5.2.3 G1收集器

5.3 實戰:性能分析方法

5.3.1 獲取GC日誌

5.3.2 GC監控信息

5.3.3 記憶體分析工具

5.3.4 選擇合適的收集器與GC性能評估

5.3.5 不要忽略JVM Crash日誌

5.4 小結

第6章 棧

6.1 硬體背景:了解真實機器

6.1.1 程式是如何運行的

6.1.2 x86與棧幀

6.1.3 ARM對Java硬體級加速:Jazelle技術

6.2 Java棧

6.2.1 暫存器式指令集與棧式指令集

6.2.2 HotSpot中的棧

6.2.3 棧幀

6.2.4 充分利用暫存器資源

6.2.5 虛擬機如何調用Java函式

6.2.6 最佳化:棧頂快取

6.2.7 實戰:運算元棧

6.3 小結

第7章 解釋器和即時編譯器

7.1 概述

7.2 解釋器如何工作

7.2.1 Interpreter模組

7.2.2 Code模組

7.2.3 位元組碼錶

7.2.4 Code Cache

7.2.5 InterpreterCodelet與Stubs佇列

7.2.6 Code生成器

7.2.7 模板表與轉發表

7.2.8 實戰:InterpreterCodelet

7.3 即時編譯器

7.3.1 概述

7.3.2 編譯器模組

7.3.3 編譯器的基本結構

7.3.4 實戰:編譯原理實踐,了解編譯中間環節

7.4 小結

第8章 指令集

8.1 再說棧式指令集

8.2 數據傳送

8.2.1 局部變數、常量池和運算元棧之間的數據傳送

8.2.2 數據傳送指令

8.2.4 實戰:數組的越界檢查

8.3 類型轉換

8.4 對象的創建和操作

8.5 程式流程控制

8.5.1 控制轉移指令

8.5.2 條件轉移

8.5.3 無條件轉移

8.5.4 複合條件轉移

8.5.5 實戰:switch語句如何使用String

8.6 運算

8.6.1 加法:iadd

8.6.2 取負:ineg

8.7 函式的調用和返回

8.7.1 Java函式分發機制:VTABLE與ITABLE

8.7.2 invoke系列指令

8.7.3 動態分發:覆蓋

8.7.4 靜態分發:重載

8.8 異常

8.8.1 異常表

8.8.2 創建異常

8.8.3 try-catch

8.8.4 finally

8.9 小結

第9章 虛擬機監控工具

9.1 Attach機制

9.1.1 AttachProvider與VirtualMachine

9.1.2 命令的下發:execute()

9.1.3 命令的執行:Attach Listener守護執行緒

9.2 查看JVM進程

9.2.1 用jps查看Java進程

9.2.2 實戰:定製jps,允許查看庫路徑

9.3 查看和配置JVM

9.3.1 用jinfo查看JVM參數配置

9.3.2 實戰:擴展flags選項,允許查看命令行參數

9.4 堆記憶體轉儲工具

9.4.1 Heap Dump

9.4.2 原理

9.5 堆轉儲分析

9.5.1 Heap Dump分析工具:jhat

9.5.2 實戰:MAT分析過程

9.6 執行緒轉儲分析

9.6.1 jstack

9.6.2 實戰:如何分析資源等待

9.7 小結

作者簡介

陳濤,碩士,畢業於中國科技大學。現就職於**,從事線上支付系統的設計與開發工作。在從事Java工作之前 ,曾有過Linux核心及驅動開發工作經驗。熱衷於專研技術,對程式語言和JVM比較感興趣。工作之餘 ,喜歡足球和武俠帶來的樂趣。目前正在“專研”的課題是如何做一名稱職的奶爸。

專家推薦

陳濤是網易寶的核心開發人員之一,同時維護了網易寶的多個系統。網易寶是網易官方的線上支付系統,對開發工程師的技術要求極高。他喜歡專研技術,知識面寬,不僅對Java、C、C++熟悉,對作業系統底層也很熟悉,能夠將理論很好地套用於實踐中。本書便是他潛心研究和實踐的成果。

——趙剛,網易寶系統負責人,資深技術專家

陳濤在Java開發領域知識的深度和廣度給我留下了深刻的印象。本書深入淺出地介紹了JVM技術,強調實踐套用。對於想深入研究JVM並希望快速取得進展的開發人員來說,本書非常具有實用價值,是Java開發水平更上一層樓的階石。

——陳雙輝,現任通策集團信息事業部CTO,曾在摩托羅拉移動擔任Senior PM

相關詞條

相關搜尋

熱門詞條

聯絡我們