深入理解Java虛擬機:JVM高級特性與最佳實踐(第3版)

2021-04-27 11:56 更新

深入理解Java虛擬機:JVM高級特性與最佳實踐(第3版)

周志明 著

  • 出版社: 機械工業(yè)出版社
  • ISBN:9787111641247
  • 版次:3
  • 商品編碼:12607299
  • 品牌:機工出版
  • 包裝:平裝
  • 叢書名: 華章原創(chuàng)精品
  • 開本:16開
  • 出版時間:2019-12-01
  • 用紙:膠版紙
  • 頁數(shù):540


點此購買


編輯推薦

適讀人群 :

  1. 使用Java技術體系的中-高級開發(fā)人員 
  2. 系統(tǒng)調優(yōu)師 
  3. 平臺架構師 
  4. 準備進互聯(lián)網(wǎng)大廠面試的 Java 開發(fā)人員

【本書示例源代碼免費提供下載,關注“華章計算機”回復“虛擬機”直接獲取源代碼下載地址】

(1)涵蓋絕大部分互聯(lián)網(wǎng)大廠面試知識點!助你順利進大廠!

(2)根據(jù)JDK12和JDK 13 EA版本全面更新,新增內容近50%,并對第2版中含糊、瑕疵和錯誤內容進行了修正。

(3)計算機圖書領域的豐碑,累計印刷超40次,銷量超過30萬冊,兩家網(wǎng)店評論數(shù)量超過90000條,內容近乎零差評。

(4)從Java技術體系、自動內存管理、虛擬機執(zhí)行子系統(tǒng)、程序編譯與代碼優(yōu)化、高效并發(fā)5個維度全面分析JVM。

(5)全書以實戰(zhàn)為導向,通過大量與實際生產(chǎn)環(huán)境相結合的案例分析和展示了解決各種Java技術難題的方案和技巧。

(6)來自阿里、騰訊、微軟、百度、滴滴、易寶支付、同盾科技、達觀數(shù)據(jù)、易觀國際、蘑菇街的10位專家高度評價并強烈推薦。

(7)這本書值得所有Java技術人員讀3遍,值得Java技術人員讀3遍,值得讀3遍!


內容簡介

這是一部從工作原理和工程實踐兩個維度深入剖析JVM的著作,是計算機領域公認的經(jīng)典,繁體版在中國臺灣地區(qū)也頗受歡迎。

自2011年上市以來,累計印刷超40次,銷量超過30萬冊,兩家主要網(wǎng)絡書店的評論近90000條,內容上近乎零差評,是原創(chuàng)計算機圖書領域不可逾越的豐碑。

第3版在第2版的基礎上做了重大修訂,內容更豐富、實戰(zhàn)性更強:根據(jù)新版JDK對內容進行了全方位的修訂和升級,圍繞新技術和生產(chǎn)實踐新增逾10萬字,包含近50%的全新內容,并對第2版中含糊、瑕疵和錯誤內容進行了修正。涵蓋互聯(lián)網(wǎng)大廠面試重要知識點!

全書一共13章,分為五大部分:

●第①部分(第1章)走近Java

系統(tǒng)介紹了Java的技術體系、發(fā)展歷程、虛擬機家族,以及動手編譯JDK,了解這部分內容能對學習JVM提供良好的指引。

●第②部分(第2~5章)自動內存管理

詳細講解了Java的內存區(qū)域與內存溢出、垃圾收集器與內存分配策略、虛擬機性能監(jiān)控與故障排除等與自動內存管理相關的內容,以及10余個經(jīng)典的性能優(yōu)化案例和優(yōu)化方法;

●第③部分(第6~9章)虛擬機執(zhí)行子系統(tǒng)

深入分析了虛擬機執(zhí)行子系統(tǒng),包括類文件結構、虛擬機類加載機制、虛擬機字節(jié)碼執(zhí)行引擎,以及多個類加載及其執(zhí)行子系統(tǒng)的實戰(zhàn)案例;

●第④部分(第10~11章)程序編譯與代碼優(yōu)化

詳細講解了程序的前、后端編譯與優(yōu)化,包括前端的易用性優(yōu)化措施,如泛型、主動裝箱拆箱、條件編譯等的內容的深入分析;以及后端的性能優(yōu)化措施,如虛擬機的熱點探測方法、HotSpot 的即時編譯器、提前編譯器,以及各種常見的編譯期優(yōu)化技術;

●第⑤部分(第12~13章)高效并發(fā)

主要講解了Java實現(xiàn)高并發(fā)的原理,包括Java的內存模型、線程與協(xié)程,以及線程安全和鎖優(yōu)化。

全書以實戰(zhàn)為導向,通過大量與實際生產(chǎn)環(huán)境相結合的案例分析和展示了解決各種Java技術難題的方案和技巧。


作者簡介

周志明(博士)

資深Java技術專家-機器學習技術專家和企業(yè)級開發(fā)技術專家,現(xiàn)任遠光軟件研究院院長。

開源技術的積極倡導者和推動者,對計算機科學相關的多個領域都有深刻的見解,尤其是人工智能-Java技術和敏捷開發(fā)等,對虛擬機技術有非常深入的研究。

撰寫了《深入理解Java虛擬機》《深入理解OSGi》《智慧的疆界》等多本著作,翻譯了《Java虛擬機規(guī)范》等著作。其中《深入理解Java虛擬機》已累計印刷逾40次,總銷超過30萬冊,成為原創(chuàng)計算機專業(yè)圖書領域難以逾越的豐碑。


精彩書評

●該書是國內近10年少見的原創(chuàng)計算機著作,它幫助國內數(shù)十萬Java開發(fā)工程師和架構師加深了對JVM的認知,提升了Java水平,不可多得。

——陳斌 易寶支付 CTO

●當年看到本書的第1版時如獲至寶,深入淺出,原理和實踐都講得很透徹,反復讀了很多遍,讓我對Java有了深入的了解。第3版在內容上有很多更新,強烈推薦給所有技術從業(yè)者。

——張新波 同盾科技聯(lián)合創(chuàng)始人兼副總裁

●本書是講解JVM原理的經(jīng)典著作,詳實地介紹了內存管理、多線程、編譯過程、執(zhí)行子系統(tǒng)、高并發(fā)優(yōu)化等關鍵技術,第3版中新增了大量新的Java技術,值得再仔細閱讀。

——陳運文 國家萬人計劃專家、達觀數(shù)據(jù)CEO

●JVM是Java的核心和基礎,深入理解它,不僅有助于提升Java程序的性能,而且能幫助我們更深入地理解底層語言的運行機制,希望本書能幫助更多Java工程師提升功力。

——郭煒 易觀國際CTO

●本書對Java內核體系進行了系統(tǒng)梳理,詳細地講解了Java中的關鍵組件和體系,如Java的內存管理、JVM系統(tǒng)的全局體系、性能調優(yōu)、高并發(fā)等,讓讀者可以非常全面地了解JVM的運行機制和調優(yōu)原理。

——羅李 滴滴大數(shù)據(jù)架構部負責人/Apache Alluxio PMC&Committer

●只有掌握JVM的原理,才能夠在高并發(fā)、大容量和低延時的極端場景下做好架構和編碼,這對程序員的要求極為嚴苛,本書為廣大Java程序員和架構師提供了非常棒的指導。

——趙成 蘑菇街技術總監(jiān)

●本書值得所有Java工程師仔細研讀,在它的基礎上再去深入挖掘,必定能對Java開發(fā)和相關系統(tǒng)的設計有真正的理解,完成從應用開發(fā)到系統(tǒng)設計的關鍵一步。

——張力柯 騰訊游戲Turing Lab副總監(jiān)

●深入理解JVM,對于提升自身的編碼素養(yǎng)至關重要。這本經(jīng)典著作為我們系統(tǒng)地理解JVM指明了方向,在銷量和口碑方面,同類書只能望其項背!

——曹洪偉 百度DuerOS布道師

●JVM是Java技術生態(tài)的基石,深入了解JVM是Java程序員進階的必修課。本書自第1版上市以來,就獲得了極好的口碑,已經(jīng)成為中國Java程序員必不可少的案頭書。

——陳耿 微軟全球黑帶技術專家/《開源容器云OpenShift》《深入淺出Serverless》作者

●這本書用平實的語言講解了JVM的關鍵功能模塊,包括自動內存管理、虛擬機執(zhí)行系統(tǒng)、字節(jié)碼優(yōu)化以及并發(fā)原理等,都是我們在使用Java的過程中會經(jīng)常用到的,很值得花時間深入研究和學習。

——沈詢 阿里資深技術專家


目錄

【第一部分 走近Java】

●第1章 走近Java 2

1.1 概述 2

1.2 Java技術體系 3

1.3 Java發(fā)展史 4

1.4 Java虛擬機家族 12

1.4.1 虛擬機始祖:Sun Classic/Exact VM 12

1.4.2 武林盟主:HotSpot VM 13

1.4.3 小家碧玉:Mobile/Embedded VM 14

1.4.4 天下第二:BEA JRockit/IBM J9 VM 15

1.4.5 軟硬合璧:BEA Liquid VM/Azul VM 16

1.4.6 挑戰(zhàn)者:Apache Harmony/Google Android Dalvik VM 17

1.4.7 沒有成功,但并非失敗:Microsoft JVM及其他 18

1.4.8 百家爭鳴 19

1.5 展望Java技術的未來 21

1.5.1 無語言傾向 21

1.5.2 新一代即時編譯器 23

1.5.3 向Native邁進 24

1.5.4 靈活的胖子 26

1.5.5 語言語法持續(xù)增強 27

1.6 實戰(zhàn):自己編譯JDK 29

1.6.1 獲取源碼 29

1.6.2 系統(tǒng)需求 31

1.6.3 構建編譯環(huán)境 33

1.6.4 進行編譯 34

1.6.5 在IDE工具中進行源碼調試 36

1.7 本章小結 39

【第二部分 自動內存管理】

●第2章 Java內存區(qū)域與內存溢出異常 42

2.1 概述 42

2.2 運行時數(shù)據(jù)區(qū)域 42

2.2.1 程序計數(shù)器 43

2.2.2 Java虛擬機棧 43

2.2.3 本地方法棧 44

2.2.4 Java堆 44

2.2.5 方法區(qū) 46

2.2.6 運行時常量池 47

2.2.7 直接內存 47

2.3 HotSpot虛擬機對象探秘 48

2.3.1 對象的創(chuàng)建 48

2.3.2 對象的內存布局 51

2.3.3 對象的訪問定位 52

2.4 實戰(zhàn):OutOfMemoryError異常 53

2.4.1 Java堆溢出 54

2.4.2 虛擬機棧和本地方法棧溢出 56

2.4.3 方法區(qū)和運行時常量池溢出 61

2.4.4 本機直接內存溢出 65

2.5 本章小結 66

●第3章 垃圾收集器與內存分配策略 67

3.1 概述 67

3.2 對象已死? 68

3.2.1 引用計數(shù)算法 68

3.2.2 可達性分析算法 70

3.2.3 再談引用 71

3.2.4 生存還是死亡? 72

3.2.5 回收方法區(qū) 74

3.3 垃圾收集算法 75

3.3.1 分代收集理論 75

3.3.2 標記-清除算法 77

3.3.3 標記-復制算法 78

3.3.4 標記-整理算法 79

3.4 HotSpot的算法細節(jié)實現(xiàn) 81

3.4.1 根節(jié)點枚舉 81

3.4.2 安全點 82

3.4.3 安全區(qū)域 83

3.4.4 記憶集與卡表 84

3.4.5 寫屏障 85

3.4.6 并發(fā)的可達性分析 87

3.5 經(jīng)典垃圾收集器 89

3.5.1 Serial收集器 90

3.5.2 ParNew收集器 92

3.5.3 Parallel Scavenge收集器 93

3.5.4 Serial Old收集器 94

3.5.5 Parallel Old收集器 95

3.5.6 CMS收集器 96

3.5.7 Garbage First收集器 98

3.6 低延遲垃圾收集器 104

3.6.1 Shenandoah收集器 105

3.6.2 ZGC收集器 112

3.7 選擇合適的垃圾收集器 121

3.7.1 Epsilon收集器 121

3.7.2 收集器的權衡 121

3.7.3 虛擬機及垃圾收集器日志 122

3.7.4 垃圾收集器參數(shù)總結 127

3.8 實戰(zhàn):內存分配與回收策略 129

3.8.1 對象優(yōu)先在Eden分配 130

3.8.2 大對象直接進入老年代 131

3.8.3 長期存活的對象將進入老年代 132

3.8.4 動態(tài)對象年齡判定 134

3.8.5 空間分配擔保 135

3.9 本章小結 137

●第4章 虛擬機性能監(jiān)控-故障處理工具 138

4.1 概述 138

4.2 基礎故障處理工具 138

4.2.1 jps:虛擬機進程狀況工具 141

4.2.2 jstat:虛擬機統(tǒng)計信息監(jiān)視工具 142

4.2.3 jinfo:Java配置信息工具 143

4.2.4 jmap:Java內存映像工具 144

4.2.5 jhat:虛擬機堆轉儲快照分析工具 145

4.2.6 jstack:Java堆棧跟蹤工具 146

4.2.7 基礎工具總結 148

4.3 可視化故障處理工具 151

4.3.1 JHSDB:基于服務性代理的調試工具 152

4.3.2 JConsole:Java監(jiān)視與管理控制臺 157

4.3.3 VisualVM:多合-故障處理工具 164

4.3.4 Java Mission Control:可持續(xù)在線的監(jiān)控工具 171

4.4 HotSpot虛擬機插件及工具 175

4.5 本章小結 180

●第5章 調優(yōu)案例分析與實戰(zhàn) 181

5.1 概述 181

5.2 案例分析 181

5.2.1 大內存硬件上的程序部署策略 182

5.2.2 集群間同步導致的內存溢出 184

5.2.3 堆外內存導致的溢出錯誤 185

5.2.4 外部命令導致系統(tǒng)緩慢 187

5.2.5 服務器虛擬機進程崩潰 187

5.2.6 不恰當數(shù)據(jù)結構導致內存占用過大 188

5.2.7 由Windows虛擬內存導致的長時間停頓 189

5.2.8 由安全點導致長時間停頓 190

5.3 實戰(zhàn):Eclipse運行速度調優(yōu) 192

5.3.1 調優(yōu)前的程序運行狀態(tài) 193

5.3.2 升級JDK版本的性能變化及兼容問題 196

5.3.3 編譯時間和類加載時間的優(yōu)化 200

5.3.4 調整內存設置控制垃圾收集頻率 203

5.3.5 選擇收集器降低延遲 206

5.4 本章小結 209

【第三部分 虛擬機執(zhí)行子系統(tǒng)】

●第6章 類文件結構 212

6.1 概述 212

6.2 無關性的基石 212

6.3 Class類文件的結構 214

6.3.1 魔數(shù)與Class文件的版本 215

6.3.2 常量池 218

6.3.3 訪問標志 224

6.3.4 類索引-父類索引與接口索引集合 225

6.3.5 字段表集合 226

6.3.6 方法表集合 229

6.3.7 屬性表集合 230

6.4 字節(jié)碼指令簡介 251

6.4.1 字節(jié)碼與數(shù)據(jù)類型 251

6.4.2 加載和存儲指令 253

6.4.3 運算指令 254

6.4.4 類型轉換指令 255

6.4.5 對象創(chuàng)建與訪問指令 256

6.4.6 操作數(shù)棧管理指令 256

6.4.7 控制轉移指令 257

6.4.8 方法調用和返回指令 257

6.4.9 異常處理指令 258

6.4.10 同步指令 258

6.5 公有設計,私有實現(xiàn) 259

6.6 Class文件結構的發(fā)展 260

6.7 本章小結 261

第7章 虛擬機類加載機制 262

7.1 概述 262

7.2 類加載的時機 263

7.3 類加載的過程 267

7.3.1 加載 267

7.3.2 驗證 268

7.3.3 準備 271

7.3.4 解析 272

7.3.5 初始化 277

7.4 類加載器 279

7.4.1 類與類加載器 280

7.4.2 雙親委派模型 281

7.4.3 破壞雙親委派模型 285

7.5 Java模塊化系統(tǒng) 287

7.5.1 模塊的兼容性 288

7.5.2 模塊化下的類加載器 290

7.6 本章小結 292

第8章 虛擬機字節(jié)碼執(zhí)行引擎 293

8.1 概述 293

8.2 運行時棧幀結構 294

8.2.1 局部變量表 294

8.2.2 操作數(shù)棧 299

8.2.3 動態(tài)連接 300

8.2.4 方法返回地址 300

8.2.5 附加信息 301

8.3 方法調用 301

8.3.1 解析 301

8.3.2 分派 303

8.4 動態(tài)類型語言支持 315

8.4.1 動態(tài)類型語言 316

8.4.2 Java與動態(tài)類型 317

8.4.3 java.lang.invoke包 318

8.4.4 invokedynamic指令 321

8.4.5 實戰(zhàn):掌控方法分派規(guī)則 324

8.5 基于棧的字節(jié)碼解釋執(zhí)行引擎 326

8.5.1 解釋執(zhí)行 327

8.5.2 基于棧的指令集與基于寄存器的指令集 328

8.5.3 基于棧的解釋器執(zhí)行過程 329

8.6 本章小結 334

第9章 類加載及執(zhí)行子系統(tǒng)的案例與實戰(zhàn) 335

9.1 概述 335

9.2 案例分析 335

9.2.1 Tomcat:正統(tǒng)的類加載器架構 335

9.2.2 OSGi:靈活的類加載器架構 338

9.2.3 字節(jié)碼生成技術與動態(tài)代理的實現(xiàn) 341

9.2.4 Backport工具:Java的時光機器 345

9.3 實戰(zhàn):自己動手實現(xiàn)遠程執(zhí)行功能 348

9.3.1 目標 348

9.3.2 思路 349

9.3.3 實現(xiàn) 350

9.3.4 驗證 355

9.4 本章小結 356

【第四部分 程序編譯與代碼優(yōu)化】

●第10章 前端編譯與優(yōu)化 358

10.1 概述 358

10.2 Javac編譯器 359

10.2.1 Javac的源碼與調試 359

10.2.2 解析與填充符號表 362

10.2.3 注解處理器 363

10.2.4 語義分析與字節(jié)碼生成 364

10.3 Java語法糖的味道 367

10.3.1 泛型 367

10.3.2 自動裝箱-拆箱與遍歷循環(huán) 375

10.3.3 條件編譯 377

10.4 實戰(zhàn):插入式注解處理器 378

10.4.1 實戰(zhàn)目標 379

10.4.2 代碼實現(xiàn) 379

10.4.3 運行與測試 385

10.4.4 其他應用案例 386

10.5 本章小結 386

●第11章 后端編譯與優(yōu)化 388

11.1 概述 388

11.2 即時編譯器 389

11.2.1 解釋器與編譯器 389

11.2.2 編譯對象與觸發(fā)條件 392

11.2.3 編譯過程 397

11.2.4 實戰(zhàn):查看及分析即時編譯結果 398

11.3 提前編譯器 404

11.3.1 提前編譯的優(yōu)劣得失 405

11.3.2 實戰(zhàn):Jaotc的提前編譯 408

11.4 編譯器優(yōu)化技術 411

11.4.1 優(yōu)化技術概覽 411

11.4.2 方法內聯(lián) 415

11.4.3 逃逸分析 417

11.4.4 公共子表達式消除 420

11.4.5 數(shù)組邊界檢查消除 421

11.5 實戰(zhàn):深入理解Graal編譯器 423

11.5.1 歷史背景 423

11.5.2 構建編譯調試環(huán)境 424

11.5.3 JVMCI編譯器接口 426

11.5.4 代碼中間表示 429

11.5.5 代碼優(yōu)化與生成 432

11.6 本章小結 436

【第五部分 高效并發(fā)】

●第12章 Java內存模型與線程 438

12.1 概述 438

12.2 硬件的效率與一致性 439

12.3 Java內存模型 440

12.3.1 主內存與工作內存 441

12.3.2 內存間交互操作 442

12.3.3 對于volatile型變量的特殊規(guī)則 444

12.3.4 針對long和double型變量的特殊規(guī)則 450

12.3.5 原子性-可見性與有序性 450

12.3.6 先行發(fā)生原則 452

12.4 Java與線程 455

12.4.1 線程的實現(xiàn) 455

12.4.2 Java線程調度 458

12.4.3 狀態(tài)轉換 460

12.5 Java與協(xié)程 461

12.5.1 內核線程的局限 461

12.5.2 協(xié)程的復蘇 462

12.5.3 Java的解決方案 464

12.6 本章小結 465

●第13章 線程安全與鎖優(yōu)化 466

13.1 概述 466

13.2 線程安全 466

13.2.1 Java語言中的線程安全 467

13.2.2 線程安全的實現(xiàn)方法 471

13.3 鎖優(yōu)化 479

13.3.1 自旋鎖與自適應自旋 479

13.3.2 鎖消除 480

13.3.3 鎖粗化 481

13.3.4 輕量級鎖 481

13.3.5 偏向鎖 483

13.4 本章小結 485

附錄A 在Windows系統(tǒng)下編譯OpenJDK 6 486

附錄B 展望Java技術的未來(2013年版) 493

附錄C 虛擬機字節(jié)碼指令表 499

附錄D 對象查詢語言(OQL)簡介 506

附錄E JDK歷史版本軌跡 512


前言/序言

【前  言】

Java是目前用戶最多-使用范圍最廣的軟件開發(fā)技術,Java的技術體系主要由支撐Java程序運行的虛擬機-提供各開發(fā)領域接口支持的Java類庫-Java編程語言及許許多多的第三方Java框架(如Spring-MyBatis等)構成。在國內,有關Java類庫API-Java語言語法及第三方框架的技術資料和書籍非常豐富,相比而言,有關Java虛擬機的資料卻顯得異常貧乏。

這種狀況很大程度上是由Java開發(fā)技術本身的一個重要優(yōu)點導致的:在虛擬機層面隱藏了底層技術的復雜性以及機器與操作系統(tǒng)的差異性。運行程序的物理機千差萬別,而Java虛擬機則在千差萬別的物理機上面建立了統(tǒng)一的運行平臺,實現(xiàn)了在任意一臺Java虛擬機上編譯的程序,都能在任何其他Java虛擬機上正常運行。這一極大的優(yōu)勢使得Java應用的開發(fā)比傳統(tǒng)C/C++應用的開發(fā)更高效快捷,程序員可以把主要精力放在具體業(yè)務邏輯,而不是放在保障物理硬件的兼容性上。通常情況下,一個程序員只要了解了必要的Java類庫API-Java語法,學習適當?shù)牡谌介_發(fā)框架,就已經(jīng)基本滿足日常開發(fā)的需要了。虛擬機會在用戶不知不覺中完成對硬件平臺的兼容及對內存等資源的管理工作。因此,了解虛擬機的運作并不是普通開發(fā)人員必備的,或者說首要學習的知識。

然而,凡事都具備兩面性。隨著Java技術的不斷發(fā)展,它已被應用于越來越多的領域之中。其中一些領域,如互聯(lián)網(wǎng)-能源-金融-通信等,對程序的性能-穩(wěn)定性和擴展性方面會有極高的要求。一段程序很可能在10個人同時使用時完全正常,但是在10 000個人同時使用時就會緩慢-死鎖甚至崩潰。毫無疑問,要滿足10 000個人同時使用,需要更高性能的物理硬件,但是在絕大多數(shù)情況下,提升硬件性能無法等比例提升程序的運行性能和并發(fā)能力,甚至有可能對程序運行狀況沒有任何改善。這里面有Java虛擬機的原因:為了達到“所有硬件提供一致的虛擬平臺”的目的,犧牲了一些硬件相關的性能特性。更重要的是人為原因:如果開發(fā)人員不了解虛擬機諸多技術特性的運行原理,就無法寫出最適合虛擬機運行和自優(yōu)化的代碼。

其實,目前商用的高性能Java虛擬機都提供了相當多的優(yōu)化參數(shù)和調節(jié)手段,用于滿足應用程序在實際生產(chǎn)環(huán)境中對性能和穩(wěn)定性的要求。如果只是為了入門學習,讓程序在自己的機器上正常工作,那么這些特性可以說是可有可無的;但是,如果用于生產(chǎn)開發(fā),尤其是大規(guī)模的-企業(yè)級的生產(chǎn)開發(fā),就迫切需要開發(fā)人員中至少有一部分人對虛擬機的特性及調節(jié)方法具有很清晰的認識。所以在Java開發(fā)體系中,對架構師-系統(tǒng)調優(yōu)師-高級程序員等角色的需求一直都非常大。學習虛擬機中各種自動運作特性的原理也成為Java程序員成長路上最終必然會接觸到的一課。通過本書,讀者可以以一個相對輕松的方式學到虛擬機的運作原理。

【本書面向的讀者】

(1)使用Java技術體系的中-高級開發(fā)人員

Java虛擬機作為中-高級開發(fā)人員修煉的必要知識,有著較高的學習門檻,本書可作為學習虛擬機的教材。

(2)系統(tǒng)調優(yōu)師

系統(tǒng)調優(yōu)師是最近幾年才興起并迅速流行起來的職業(yè),本書中的大量案例-代碼和調優(yōu)實戰(zhàn)將會對系統(tǒng)調優(yōu)師的日常工作有直接的參考作用。

(3)系統(tǒng)架構師

保障系統(tǒng)的性能-并發(fā)和伸縮等能力是系統(tǒng)架構師的主要職責之一,而這部分與虛擬機的運作密不可分,本書可以作為他們制定應用系統(tǒng)底層框架的參考資料。

【如何閱讀本書】

本書一共分為五個部分:走近Java-自動內存管理-虛擬機執(zhí)行子系統(tǒng)-程序編譯與代碼優(yōu)化-高效并發(fā)。各個部分之間基本上是互相獨立的,沒有必然的前后依賴關系,讀者可以從任何一個感興趣的專題開始閱讀,但是每個部分各個章節(jié)間則有先后順序。

這里并沒有假定所有讀者都在Java領域具備特別專業(yè)的技術水平,因此會在保證邏輯完整-描述準確的前提下,盡量用通俗的語言和案例去講述虛擬機中與開發(fā)關系最為密切的內容。但是,本書畢竟是在探討虛擬機的工作原理,不可避免地需要讀者有一定的技術基礎,而且本書的讀者定位是中-高級程序員群體,對于一些常用的開發(fā)框架-Java類庫API和Java語法等基礎知識點,將假設讀者已有所了解。

本書介紹的Java虛擬機并不局限于某一個特定發(fā)行商或者某一款特定虛擬機,只是由于OracleJDK/OpenJDK在市場占有率上的絕對優(yōu)勢,其中的HotSpot虛擬機不可避免地成為本書主要分析-講解的對象,書中在涉及Java虛擬機自身實現(xiàn)相關的內容時,大多將以HotSpot虛擬機為目標對象來進行講解。但撰寫本書的意圖并不是去做HotSpot的源碼導讀或者解析,書中所講述的內容多為Java虛擬機的通用原理,即使讀者使用了HotSpot之外的其他Java虛擬機實現(xiàn),也會有所收獲。

最后,非常希望讀者能跟隨本書的講解,把與實踐相關的內容親自驗證一遍,其中用到的代碼清單可以從華章圖書的網(wǎng)站(http://www.hzbook.com/)上下載。

【語言約定】

開始閱讀本書之前,在語言和技術上先與讀者建立如下約定:

JDK從1.5版本開始,其官方的正式文檔與宣傳材料中的發(fā)行版本號啟用了JDK 5-6-7……的新命名方式;從2018年3月發(fā)布的JDK 10起,JDK的開發(fā)版本號(如java -version)也放棄了以前1.x的命名形式,改為按發(fā)布的日期時間命名。本書為了行文一致,所有場合統(tǒng)一采用發(fā)行版本號來指代所述的JDK版本。

由于版面原因,本書中的許多示例代碼都沒有遵循最優(yōu)的程序編寫風格,如使用的流沒有關閉流-直接使用System.out輸出日志等,請讀者在閱讀時注意這一點。

本書講解中涉及JDK 7以前HotSpot虛擬機-JRockit虛擬機-WebLogic服務器等產(chǎn)品的所有者時,仍然會使用BEA和Sun公司的名稱,而不是Oracle。實際上BEA和Sun分別于2008年和2010年被Oracle公司收購,現(xiàn)在已經(jīng)不存在這兩個商標了,但是它們毫無疑問都是在Java領域中做出過卓越貢獻的-值得程序員們紀念的先驅企業(yè)。

本書第3版撰寫于2019年中期,此時JDK 13已有了技術預覽版(Early Access),但尚未正式發(fā)布。本書中所有的講解-討論都是基于這個時間點的Java技術的,但并不針對特定的JDK版本。如涉及JDK新版本中加入的功能,或在不同版本中有所變化的特性,筆者都會明確指出JDK的版本號,或專門闡述各個版本間的差異。

【內容特色與更新】

本書的第2版成文于2011至2012年間,出版于2013年,撰寫時是基于早期版本的JDK 7,彼時正值Oracle全面替代Sun公司領導Java技術發(fā)展的起點。經(jīng)過將近十年的時間,今天JDK版本已經(jīng)發(fā)展到了JDK 12及預覽版的JDK 13,整個Java技術體系一改Sun時代的遲緩作風,出現(xiàn)了許多激烈的變革,也涌現(xiàn)了不少令人欣喜的新變化-新風潮。我在撰寫本書第3版時,期望能把這些新的變化融合到已有的知識框架中,修改第2版中讀者反饋的問題,提升敘述的準確性與可讀性,這些期望中的更新使得本書字數(shù)從原有的24萬增加到35萬。因此,在前言部分,筆者針對每章列舉出主要更新的內容,以便閱讀過第2版的讀者可以快速定位,獲取到新的知識。當然,如果你尚有余暇,不妨從頭閱讀一次本書,相信會有與閱讀第2版時不一樣的體驗和收獲。

●第一部分 走近Java

本書的第一部分為后文的研究和講解建立了良好的基礎。雖然了解Java技術的來龍去脈,以及編譯自己的OpenJDK對于讀者理解Java虛擬機并不是必須的,但是這些準備過程可以為走近Java技術和Java虛擬機提供良好的引導。第一部分只有第1章:

第1章 介紹了Java技術體系過去-現(xiàn)在的情況以及未來的發(fā)展趨勢,并在實踐中介紹了如何自己編譯一個OpenJDK 12。

第3版更新:續(xù)寫了Java技術發(fā)展史,這幾年Java世界著實發(fā)生了很多值得記錄的大事件;完全重寫了第2版對未來Java的展望預測,當時暢想的Java新發(fā)展新變化全部如約而至,是時候把聚光燈交給下一個十年的Java了;OpenJDK開發(fā)-編譯也發(fā)生過不小的變動,本次更新將OpenJDK編譯的版本提升到12。

●第二部分 自動內存管理

因為程序員把控制內存的權力交給了Java虛擬機,所以可以在編碼的時候享受自動內存管理的諸多優(yōu)勢,不過也正因為這個原因,一旦出現(xiàn)內存泄漏和溢出方面的問題,如果不了解虛擬機是怎樣使用內存的,那排查錯誤將會成為一項異常艱難的工作。第二部分包括第2~5章:

第2章 介紹了虛擬機中內存是如何劃分的,哪部分區(qū)域-什么樣的代碼和操作可能導致內存溢出異常,并講解了各個區(qū)域出現(xiàn)內存溢出異常的常見原因。

第3版更新:Java運行期數(shù)據(jù)區(qū)域是虛擬機的基礎結構,盡管JDK版本在快速發(fā)展,這塊內容仍然保持了相對的穩(wěn)定,主要的變化是JDK 8時期的永久代的落幕和元空間的登場;除此以外,本章著重修正了第2版中對Java虛擬機棧描述的含糊與偏差之處,還更新了部分測試代碼,避免因JDK版本更迭導致與書中不一樣的結果。

第3章 介紹了垃圾收集的算法和HotSpot虛擬機中提供的幾款垃圾收集器的特點及運作原理。通過代碼實例驗證了Java虛擬機中自動內存分配及回收的主要規(guī)則。

第3版更新:由于撰寫第2版時JDK 7剛剛發(fā)布,G1收集器尚無實踐數(shù)據(jù)可查,書中對此講述得比較含糊,本次更新完全重寫了這部分內容,并重點增加了JDK 11-12中新出現(xiàn)的ZGC和Shenandoah兩款低延遲全并發(fā)收集器的詳細原理解析,這是垃圾收集器未來的發(fā)展方向。對其他與收集器相關的更新,如統(tǒng)一收集器接口-Epsilon等也都做了對應介紹。此外,針對HotSpot中收集器實現(xiàn)的幾個關鍵技術點,如解決跨代引用的記憶集與卡表-解決并發(fā)標記的增量更新和原始快照算法,還有內存讀-寫屏障等技術都增加了專門的小節(jié)來進行介紹,以便幫讀者在后續(xù)深入閱讀HotSpot設計與源碼時打下良好的理論基礎。

第4章 介紹了隨JDK發(fā)布的基礎命令行工具與可視化的故障處理工具的使用方法。

第3版更新:Java虛擬機的各種監(jiān)控-管理等輔助工具的功能日益強大,幾乎每個版本在這些工具的數(shù)量-功能上都會或多或少有所變化,除了將第2版涉及的工具的變化依照JDK版本進行升級外,本章還新增了對JDK 9中加入的JHSDB的使用講解,并增加了對JFR和JMC的工作原理和使用方法的介紹,以及對部分JDK外部的工具(如JIT Watch)的簡要介紹。

第5章 分享了幾個比較有代表性的實際案例,還準備了一個所有開發(fā)人員都能“親身實戰(zhàn)”的練習,希望讀者能通過實踐來獲得故障處理和調優(yōu)的經(jīng)驗。

第3版更新:對案例部分進行了更新和增補,著重補充了與前3章新增內容相對應的問題處理案例。不過對實戰(zhàn)部分,軟件版本的落后并未影響筆者要表達的內容,原有的實戰(zhàn)目前仍具有相同的實戰(zhàn)價值,在第3版里筆者也并未刻意將Eclipse和HotSpot升級后重寫一次。

●第三部分 虛擬機執(zhí)行子系統(tǒng)

執(zhí)行子系統(tǒng)是虛擬機中必不可少的組成部分,了解了虛擬機如何執(zhí)行程序,才能更好地理解怎樣才能寫出優(yōu)秀的代碼。第三部分包括第6~9章:

第6章 講解了Class文件結構中的各個組成部分,以及每個部分的定義-數(shù)據(jù)結構和使用方法,以實戰(zhàn)的方式演示了Class的數(shù)據(jù)是如何存儲和訪問的。

第3版更新:筆者認為本章內容更適合以“技術手冊”的形式存在,即適合查閱多于適合閱讀,但因為Class文件格式是虛擬機的基礎知識,所以盡管枯燥卻無法回避。本次更新將Class文件格式的版本跟進到了JDK 12,《Java虛擬機規(guī)范》對Class文件格式進行的增強也會在本章中反映,內容相對瑣碎。例如,為了實現(xiàn)JDK 9的Java模塊化系統(tǒng),屬性表中新增了Module-ModulePackages-ModuleMain-Class三項新屬性,常量池中加入了CONSTANT_Module_info和CONSTANT_Package_info兩個常量。為了實現(xiàn)JDK 11新增的嵌套內(Java中的內部類)訪問控制的API,屬性表中又增加了NestHost和NestMembers兩項屬性。為進一步加強動態(tài)語言支持,CONSTANT_Dynamic_info常量也在JDK 11期間加入常量池……

第7章 介紹了類加載過程的“加載”“驗證”“準備”“解析”和“初始化”五個階段中虛擬機分別進行了哪些動作,還介紹了類加載器的工作原理及其對虛擬機的意義。

第3版更新:隨著Class文件格式的發(fā)展,類加載的各個過程都發(fā)生了一些細節(jié)性變動,本章將會按照JDK 12版本的《Java虛擬機規(guī)范》的標準來同步更新這些內容。此外,在JDK 9時引入了Java模塊化系統(tǒng),這是近年來Java技術的一次重要升級,也是對類加載部分影響巨大的一項變革,在本章將加入專門的小節(jié)對其進行講述。

第8章 分析了虛擬機在執(zhí)行代碼時,如何找到正確的方法-如何執(zhí)行方法內的字節(jié)碼,以及執(zhí)行代碼時涉及的內存結構。

第3版更新:本章講述的是Java虛擬機執(zhí)行子系統(tǒng)的概念模型,這部分屬于相對穩(wěn)定的內容,變化不大,本次主要更新了Java虛擬機對動態(tài)類型語言支持的增強。

第9章 通過幾個類加載及執(zhí)行子系統(tǒng)的案例,介紹了使用類加載器和處理字節(jié)碼的一些值得欣賞和借鑒的思路,并通過一個實戰(zhàn)練習加深讀者對前面理論知識的理解。

第3版更新:原有章節(jié)所涉及的案例中,程序-類庫-工具的版本已經(jīng)較為陳舊,本次更新對這些案例涉及的版本進行了升級,以反映在模塊化-Lambda表達式-動態(tài)語言等新技術出現(xiàn)后它們的相應變化。

●第四部分 程序編譯與代碼優(yōu)化

Java程序從源碼編譯成字節(jié)碼,再從字節(jié)碼編譯成本地機器碼的這兩個過程,從整體來看其實等同于一個傳統(tǒng)編譯器所執(zhí)行的編譯前端-后端過程。第四部分包括第10~11章:

第10章 分析了Java語言中泛型-主動裝箱拆箱-條件編譯等多種語法糖的前因后果,并實戰(zhàn)練習了如何使用插入式注解處理器來完成一個檢查程序命名規(guī)范的編譯器插件。

第3版更新:對第2版介紹泛型的小節(jié)進行了全文重寫,描述了不同語言里泛型實現(xiàn)的方式-Java泛型出現(xiàn)的歷史背景和使用類型擦除來實現(xiàn)泛型所帶來的一些限制,并介紹了未來可能會在Java中出現(xiàn)的值類型等內容。

第11章 講解了虛擬機的熱點探測方法-HotSpot的即時編譯器-編譯觸發(fā)條件,以及如何從虛擬機外部觀察和分析即時編譯的數(shù)據(jù)和結果,還選擇了幾種常見的編譯期優(yōu)化技術進行講解。

第3版更新:專門增加了介紹提前編譯器的章節(jié);由于HotSpot中新的Graal編譯器的加入,書中除了同步增加Graal編譯器-JVMCI接口等內容,為了使讀者可以在HotSpot編譯器上進行實戰(zhàn)練習,在本書第3版中還新增了許多編譯器的實戰(zhàn)內容。

●第五部分 高效并發(fā)

Java語言和虛擬機提供了原生的-完善的多線程支持,使得它天生就適合開發(fā)多線程并發(fā)的應用程序。不過我們不能期望系統(tǒng)來完成所有與并發(fā)相關的處理,了解并發(fā)的內幕也是成為一位高級程序員不可缺少的課程。第五部分包括第12~13章:

第12章 講解了虛擬機Java內存模型的結構及操作,以及原子性-可見性和有序性在Java內存模型中的體現(xiàn);介紹了先行發(fā)生原則的規(guī)則及使用,以及線程在Java語言之中是如何實現(xiàn)的;還提前介紹了目前仍然在實驗室狀態(tài)的Java協(xié)程的相關內容。

第3版更新:重寫了原有的對Java內存模型部分過時和過于晦澀的描述,增加了面向Java未來基于協(xié)程的新并發(fā)模型的介紹。

第13章 介紹了線程安全所涉及的概念和分類-同步實現(xiàn)的方式及虛擬機的底層運作原理,并且介紹了虛擬機實現(xiàn)高效并發(fā)所做的一系列鎖優(yōu)化措施。

第3版更新:本章主體內容并沒有過多變化,但對不少細節(jié)進行了修飾,對一些讀者疑問較多的地方進行了補充講解。

【致  謝】

首先要感謝我的家人,在本書寫作期間全靠他們對我的悉心照顧,才讓我能夠全身心地投入到寫作之中,而無后顧之憂。

其次要感謝本書第1-2版的讀者們,因你們的支持,讓本書成為國內暢銷的原創(chuàng)編程書籍之一,累計印刷36次,銷量超過30萬冊;因你們的反饋,讓我能夠在新版中修正前兩版里若干不成熟-不完整,乃至不正確的地方。

同時要感謝我的工作單位遠光軟件,公司為我提供了寶貴的工作-學習和實踐的環(huán)境,書中的許多知識點都來自于工作實踐;也感謝與我一起工作的同事們,非常榮幸能與你們一起在這個富有激情的團隊中共同奮斗。

還要專門感謝莫樞(@RednaxelaFX),我認為他是國內對高級語言虛擬機知識普及最有貢獻的幾個人之一。尤其感謝他在百忙之中抽空審閱本書,提出了許多寶貴的建議和意見。

最后,感謝機械工業(yè)出版社華章公司的編輯,本書能夠順利出版,離不開他們的敬業(yè)精神和一絲不茍的工作態(tài)度。

周志明


點此購買


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號