內容簡介
《深入理解Java虛擬機:JVM高級特性與最佳實踐》內容簡介:作為一位Java程式設計師,你是否也曾經想深入理解Java虛擬機,但是卻被它的複雜和深奧拒之門外?沒關係,本書極盡化繁為簡之妙,能帶領你在輕鬆中領略Java虛擬機的奧秘。本書是近年來國內出版的唯一一本與Java虛擬機相關的專著,也是唯一一本同時從核心理論和實際運用這兩個角度去探討Java虛擬機的著作,不僅理論分析得透徹,而且書中包含的典型案例和最佳實踐也極具現實指導意義。
全書共分為五大部分。第一部分從巨觀的角度介紹了整個Java技術體系的過去、現在和未來,以及如何獨立地編譯一個OpenJDK7,這對理解後面的內容很有幫助。第二部分講解了JVM的自動記憶體管理,包括虛擬機記憶體區域的劃分原理以及各種記憶體溢出異常產生的原因;常見的垃圾收集算法以及垃圾收集器的特點和工作原理;常見的虛擬機的監控與調試工具的原理和使用方法。第三部分分析了虛擬機的執行子系統,包括Class的檔案結構以及如何存儲和訪問Class中的數據;虛擬機的類創建機制以及類載入器的工作原理和它對虛擬機的意義;虛擬機位元組碼的執行引擎以及它在實行代碼時涉及的記憶體結構。第四部分講解了程式的編譯與代碼的最佳化,闡述了泛型、自動裝箱拆箱、條件編譯等語法糖的原理;講解了虛擬機的熱點探測方法、HotSpot的即時編譯器、編譯觸發條件,以及如何從虛擬機外部觀察和分析JIT編譯的數據和結果。第五部分探討了Java實現高效並發的原理,包括JVM記憶體模型的結構和操作;原子性、可見性和有序性在Java記憶體模型中的體現;先行發生原則的規則和使用;執行緒在Java語言中的實現原理;虛擬機實現高效並發所做的一系列鎖最佳化措施。
本書適合所有Java程式設計師、系統調優師和系統架構師閱讀。
編輯推薦
《深入理解Java虛擬機:JVM高級特性與最佳實踐》編輯推薦:圍繞記憶體管理、執行子系統、編程編譯與最佳化、高效並發等核心內容對JVM進行全面而深入的分析,深刻揭示JVM的工作原理;注重實現,以解決實踐中的疑難問題為首要目的,包含大量經典案例和最佳實踐。
媒體推薦
Java 程式是如何運行的?Java虛擬機在其中扮演了怎樣的角色?如何讓Java程式具有更高的並發性?許多Java程式設計師都會諸如此類的疑問。無奈,國內在很長一段時間裡都沒有一本從實際套用的角度講解Java虛擬機的著作,《深入理解Java虛擬機:JVM高級特性與最佳實踐》的出版可謂填補了這個空白。它從Java程式設計師的角度出發,系統地將Java程式運行過程中涉及的各種知識整合到了一起,並配以日常工作中可能會碰到的疑難案例,引領讀者輕鬆踏上探索Java虛擬機的旅途,是廣大對Java虛擬機感興趣的讀者的福音!
——莫樞(RednaxelaFX) 虛擬機和程式語言愛好者
在武俠的世界裡,無論是至剛至強的《易筋經》,還是陰柔無比的《葵花寶典》,都離不開內功修煉。沒有了內功心法,這些武術只是花拳繡腿的拙劣表演而已。軟體業是武林江湖的一個翻版,也有著大量的模式、套路、規範等外功,但“外功修行,內功修神”,要想成為“掃地僧”一樣的絕世高人,此書是必備的。
——秦小波 資深Java技術專家/著有暢銷書《設計模式之禪》
對Java程式設計師來說,Java虛擬機可以說是既熟悉又神秘,很少Java程式設計師能夠抑制自己探究它的衝動。可惜,分析JVM實現原理的書籍(特別是國內作者出版的)是少之又少。《深入理解Java虛擬機:JVM高級特性與最佳實踐》的出版可謂Java程式設計師的福音,作者將自己多年來在Java虛擬機領域的實踐經驗和研究心得呈現在了這《深入理解Java虛擬機:JVM高級特性與最佳實踐》中,不僅系統地講解了Java虛擬機工作機制和底層原理,而且更難能可貴的是與實踐很好地結合了起來,具有非常強的實踐指導意義,強烈推薦!
——計文柯 資深Java技術專家/著有暢銷書《Spring技術內幕:深入解析Spring架構設計與實現原理》
圖書目錄
前言
致謝
第一部分 走近Java
第1章 走近Java / 2
1.1 概述 / 2
1.2 Java技術體系 / 3
1.3 Java發展史 / 5
1.4 展望Java技術的未來 / 9
1.4.1 模組化 / 9
1.4.2 混合語言 / 9
1.4.3 多核並行 / 11
1.4.4 進一步豐富語法 / 12
1.4.5 64位虛擬機 / 13
1.5 實戰:自己編譯JDK / 13
1.5.1 獲取JDK源碼 / 13
1.5.2 系統需求 / 14
1.5.3 構建編譯環境 / 15
1.5.4 準備依賴項 / 17
1.5.5 進行編譯 / 18
1.6 本章小結 / 21
第二部分 自動記憶體管理機制
第2章 Java記憶體區域與記憶體溢出異常 / 24
2.1 概述 / 24
2.2 運行時數據區域 / 25
2.2.1 程式計數器 / 25
2.2.2 Java虛擬機棧 / 26
2.2.3 本地方法棧 / 27
2.2.4 Java堆 / 27
2.2.5 方法區 / 28
2.2.6 運行時常量池 / 29
2.2.7 直接記憶體 / 29
2.3 對象訪問 / 30
2.4 實戰:OutOfMemoryError異常 / 32
2.4.1 Java堆溢出 / 32
2.4.2 虛擬機棧和本地方法棧溢出 / 35
2.4.3 運行時常量池溢出 / 38
2.4.4 方法區溢出 / 39
2.4.5 本機直接記憶體溢出 / 41
2.5 本章小結 / 42
第3章 垃圾收集器與記憶體分配策略 / 43
3.1 概述 / 43
3.2 對象已死? / 44
3.2.1 引用計數算法 / 44
3.2.2 根搜尋算法 / 46
3.2.3 再談引用 / 47
3.2.4 生存還是死亡? / 48
3.2.5 回收方法區 / 50
3.3 垃圾收集算法 / 51
3.3.1 標記 -清除算法 / 51
3.3.2 複製算法 / 52
3.3.3 標記-整理算法 / 54
3.3.4 分代收集算法 / 54
3.4 垃圾收集器 / 55
3.4.1 Serial收集器 / 56
3.4.2 ParNew收集器 / 57
3.4.3 Parallel Scavenge收集器 / 59
3.4.4 Serial Old收集器 / 60
3.4.5 Parallel Old收集器 / 61
3.4.6 CMS收集器 / 61
3.4.7 G1收集器 / 64
3.4.8 垃圾收集器參數總結 / 64
3.5 記憶體分配與回收策略 / 65
3.5.1 對象優先在Eden分配 / 66
3.5.2 大對象直接進入老年代 / 68
3.5.3 長期存活的對象將進入老年代 / 69
3.5.4 動態對象年齡判定 / 71
3.5.5 空間分配擔保 / 73
3.6 本章小結 / 75
第4章 虛擬機性能監控與故障處理工具 / 76
4.1 概述 / 76
4.2 JDK的命令行工具 / 76
4.2.1 jps:虛擬機進程狀況工具 / 79
4.2.2 jstat:虛擬機統計信息監視工具 / 80
4.2.3 jinfo:Java配置信息工具 / 82
4.2.4 jmap:Java記憶體映像工具 / 82
4.2.5 jhat:虛擬機堆轉儲快照分析工具 / 84
4.2.6 jstack:Java堆疊跟蹤工具 / 85
4.3 JDK的可視化工具 / 87
4.3.1 JConsole:Java監視與管理控制台 / 88
4.3.2 VisualVM:多合一故障處理工具 / 96
4.4 本章小結 / 105
第5章 調優案例分析與實戰 / 106
5.1 概述 / 106
5.2 案例分析 / 106
5.2.1 高性能硬體上的程式部署策略 / 106
5.2.2 集群間同步導致的記憶體溢出 / 109
5.2.3 堆外記憶體導致的溢出錯誤 / 110
5.2.4 外部命令導致系統緩慢 / 112
5.2.5 伺服器JVM進程崩潰 / 113
5.3 實戰:Eclipse運行速度調優 / 114
5.3.1 調優前的程式運行狀態 / 114
5.3.2 升級JDK 1.6的性能變化及兼容問題 / 117
5.3.3 編譯時間和類載入時間的最佳化 / 122
5.3.4 調整記憶體設定控制垃圾收集頻率 / 126
5.3.5 選擇收集器降低延遲 / 130
5.4 本章小結 / 133
第三部分 虛擬機執行子系統
第6章 類檔案結構 / 136
6.1 概述 / 136
6.2 無關性的基石 / 136
6.3 Class類檔案的結構 / 138
6.3.1 魔數與Class檔案的版本 / 139
6.3.2 常量池 / 141
6.3.3 訪問標誌 / 147
6.3.4 類索引、父類索引與接口索引集合 / 148
6.3.5 欄位表集合 / 149
6.3.6 方法表集合 / 153
6.3.7 屬性表集合 / 155
6.4 Class檔案結構的發展 / 168
6.5 本章小結 / 170
第7章 虛擬機類載入機制 / 171
7.1 概述 / 171
7.2 類載入的時機 / 172
7.3 類載入的過程 / 176
7.3.1 載入 / 176
7.3.2 驗證 / 178
7.3.3 準備 / 181
7.3.4 解析 / 182
7.3.5 初始化 / 186
7.4 類載入器 / 189
7.4.1 類與類載入器 / 189
7.4.2 雙親委派模型 / 191
7.4.3 破壞雙親委派模型 / 194
7.5 本章小結 / 197
第8章 虛擬機位元組碼執行引擎 / 198
8.1 概述 / 198
8.2 運行時棧幀結構 / 199
8.2.1 局部變數表 / 199
8.2.2 運算元棧 / 204
8.2.3 動態連線 / 206
8.2.4 方法返回地址 / 206
8.2.5 附加信息 / 207
8.3 方法調用 / 207
8.3.1 解析 / 207
8.3.2 分派 / 209
8.4 基於棧的位元組碼解釋執行引擎 / 221
8.4.1 解釋執行 / 221
8.4.2 基於棧的指令集與基於暫存器的指令集 / 223
8.4.3 基於棧的解釋器執行過程 / 224
8.5 本章小結 / 230
第9章 類載入及執行子系統的案例與實戰 / 231
9.1 概述 / 231
9.2 案例分析 / 231
9.2.1 Tomcat:正統的類載入器架構 / 232
9.2.2 OSGi:靈活的類載入器架構 / 235
9.2.3 位元組碼生成技術與動態代理的實現 / 238
9.2.4 Retrotranslator:跨越JDK版本 / 242
9.3 實戰:自己動手實現遠程執行功能 / 246
9.3.1 目標 / 246
9.3.2 思路 / 247
9.3.3 實現 / 248
9.3.4 驗證 / 255
9.4 本章小結 / 256
第四部分 程式編譯與代碼最佳化
第10章 早期(編譯期)最佳化 / 258
10.1 概述 / 258
10.2 Javac編譯器 / 259
10.2.1 Javac的源碼與調試 / 259
10.2.2 解析與填充符號表 / 262
10.2.3 註解處理器 / 264
10.2.4 語義分析與位元組碼生成 / 264
10.3 Java語法糖的味道 / 268
10.3.1 泛型與類型擦除 / 268
10.3.2 自動裝箱、拆箱與遍歷循環 / 273
10.3.3 條件編譯 / 275
10.4 實戰:插入式註解處理器 / 276
10.4.1 實戰目標 / 276
10.4.2 代碼實現 / 277
10.4.3 運行與測試 / 284
10.4.4 其他套用案例 / 286
10.5 本章小結 / 286
第11章 晚期(運行期)最佳化 / 287
11.1 概述 / 287
11.2 HotSpot虛擬機內的即時編譯器 / 288
11.2.1 解釋器與編譯器 / 288
11.2.2 編譯對象與觸發條件 / 291
11.2.3 編譯過程 / 294
11.2.4 查看與分析即時編譯結果 / 297
11.3 編譯最佳化技術 / 301
11.3.1 最佳化技術概覽 / 301
11.3.2 公共子表達式消除 / 305
11.3.3 數組邊界檢查消除 / 307
11.3.4 方法內聯 / 307
11.3.5 逃逸分析 / 309
11.4 Java與C/C++的編譯器對比 / 311
11.5 本章小結 / 313
第五部分 高效並發
第12章 Java記憶體模型與執行緒 / 316
12.1 概述 / 316
12.2 硬體的效率與一致性 / 317
12.3 Java記憶體模型 / 318
12.3.1 主記憶體與工作記憶體 / 319
12.3.2 記憶體間互動操作 / 320
12.3.3 對於volatile型變數的特殊規則 / 322
12.3.4 對於long和double型變數的特殊規則 / 327
12.3.5 原子性、可見性與有序性 / 328
12.3.6 先行發生原則 / 330
12.4 Java與執行緒 / 333
12.4.1 執行緒的實現 / 333
12.4.2 Java執行緒調度 / 337
12.4.3 狀態轉換 / 339
12.5 本章小結 / 341
第13章 執行緒安全與鎖最佳化 / 342
13.1 概述 / 342
13.2 執行緒安全 / 343
13.2.1 Java語言中的執行緒安全 / 343
13.2.2 執行緒安全的實現方法 / 348
13.3 鎖最佳化 / 356
13.3.1 自旋鎖與自適應自旋 / 356
13.3.2 鎖消除 / 357
13.3.3 鎖粗化 / 358
13.3.4 輕量級鎖 / 358
13.3.5 偏向鎖 / 361
13.4 本章小結 / 362
附錄A Java虛擬機家族 / 363
附錄B 虛擬機位元組碼指令表 / 366
附錄C HotSpot虛擬機主要參數表 / 372
附錄D 對象查詢語言(OQL)簡介 / 376
附錄E JDK歷史版本軌跡 / 383
作者簡介
周志明,資深Java技術專家,對JavaEE企業級套用開發、OSGi、Java虛擬機和工作流等都有深入的研究,並在大量的實踐中積累了豐富的經驗。尤其精通Java虛擬機,撰寫了大量與JVM相關的經典文章,被各大技術社區爭相轉載,是ITeye等技術社區公認的Java虛擬機方面的領袖人物之一。現任遠光軟體股份有限公司平台開發部經理兼平台架構師,先後參加與過國家電網、南方電網等多個國家級大型ERP項目的平台架構工作,對軟體系統架構也有深刻的認識和體會。
序言
Java是目前用戶最多、使用範圍最廣的軟體開發技術,Java的技術體系主要由支撐Java程式運行的虛擬機、為各開發領域提供接口支持的Java API、Java程式語言及許許多多的第三方Java框架(如Spring和Struts等)構成。在國內,有關Java API、Java語言及第三方框架的技術資料和書籍非常豐富,相比之下,有關Java虛擬機的資料卻顯得異常貧乏。
這種狀況很大程度上是由Java開發技術本身的一個重要優點導致的:在虛擬機層面隱藏了底層技術的複雜性以及機器與作業系統的差異性。運行程式的物理機器情況千差萬別,而Java虛擬機則在千差萬別的物理機上面建立了統一的運行平台,實現了在任意一台虛擬機上編譯的程式都能在任何一台虛擬機上正常運行。這一極大的優勢使得Java套用的開發比傳統C/C++套用的開發更高效和快捷,程式設計師可以把主要精力集中在具體業務邏輯上,而不是物理硬體的兼容性上。一般情況下,一個程式設計師只要了解了必要的Java API、Java語法並學習適當的第三方開發框架,就已經基本能滿足日常開發的需要了,虛擬機會在用戶不知不覺中完成對硬體平台的兼容以及對記憶體等資源的管理工作。因此,了解虛擬機的運作並不是一般開發人員必須掌握的知識。
然而,凡事都具備兩面性。隨著Java技術的不斷發展,它被套用于越來越多的領域之中。其中一些領域,如電力、金融、通信等,對程式的性能、穩定性和可擴展性方面都有極高的要求。一個程式很可能在10個人同時使用時完全正常,但是在10000個人同時使用時就會變慢、死鎖甚至崩潰。毫無疑問,要滿足10000個人同時使用需要更高性能的物理硬體,但是在絕大多數情況下,提升硬體效能無法等比例地提升程式的性能和並發能力,有時甚至可能對程式的性能沒有任何改善作用。這裡面有Java虛擬機的原因:為了達到為所有硬體提供一致的虛擬平台的目的,犧牲了一些硬體相關的性能特性。更重要的是人為原因:開發人員如果不了解虛擬機的一些技術特性的運行原理,就無法寫出最適合虛擬機運行和可自最佳化的代碼。
其實,目前商用的高性能Java虛擬機都提供了相當多的最佳化特性和調節手段,用於滿足應用程式在實際生產環境中對性能和穩定性的要求。如果只是為了入門學習,讓程式在自己的機器上正常運行,那么這些特性可以說是可有可無的;如果用於生產環境,尤其是企業級套用開發中,就迫切需要開發人員中至少有一部分人對虛擬機的特性及調節方法具有很清晰的認識,所以在Java開發體系中,對架構師、系統調優師、高級程式設計師等角色的需求一直都非常大。學習虛擬機中各種自動運作的特性的原理也成為了Java程式設計師成長道路上必然會接觸到的一課。通過本書,讀者可以以一種相對輕鬆的方式學習虛擬機的運作原理,對Java程式設計師的成長也有較大的幫助。