Java性能優化實踐 JVM調優策略 工具與技巧
[英]本傑明·J. 埃文斯(Benjamin J. Evans),[英]詹姆斯·高夫(James Gough),[英]克裡斯·紐蘭(Chris Newland)
相關主題
商品描述
本書從實驗科學的角度探討了Java性能優化的方方面面,重點闡述了最新的實用JVM性能調優策略、工具和技巧。通過本書,我們不僅可以瞭解Java原理和技術如何充分利用現代硬件和操作系統、衡量Java性能的陷阱以及微基準測試的弊端有哪些,還能深入研究可能使團隊煩惱的幾種性能測試和常見反模式、JVM垃圾收集、JIT編譯和Java語言性能技術等。本書為讀者打開了深入理解Java性能的大門,並以路標助力其優化之旅。
作者簡介
本傑明·J.埃文斯(Benjamin J.Evans),初創公司jClarity聯合創始人和技術Fellow,獲得過Java Champion榮譽和JavaOne Rockstar獎,《Java程序員修煉之道》合著者。
詹姆斯·高夫(James Gough),Java開發者和技術圖書作者,任職於摩根士丹利,專注構建面向客戶的技術。
克里斯·紐蘭(Chris Newland),JITWatch項目作者,Java Champion榮譽得主,ADVFN高級開發者和團隊負責人,擅長使用Java來處理實時的股市數據。
【譯者介紹】
曾波,互聯網架構師,擁有13年互聯網從業經驗,曾任職於微軟、什麼值得買、京東金融、鵬博士電信傳媒集團,曾參與多家公司的技術團隊從建立到成熟的過程,主持實施了重大技術決策和技術落地,在大規模複雜系統架構和技術管理方面擁有豐富的實踐經驗。
目錄大綱
中文版推薦序一 xv
中文版推薦序二 xvi
序 xvii
前言 xix
第 1 章 明確優化與性能 1
1.1 關於Java性能的誤解 1
1.2 Java性能概覽 2
1.3 作為實驗科學的性能 3
1.4 性能分類方法 4
1.4.1 吞吐量 4
1.4.2 延遲 5
1.4.3 容量 5
1.4.4 利用率 5
1.4.5 效率 5
1.4.6 可擴展性 5
1.4.7 降級 6
1.4.8 各種性能觀測之間的關聯 6
1.5 閱讀性能圖 7
1.6 小結 11
第 2 章 JVM概覽 12
2.1 解釋和類加載 12
2.2 執行字節碼 13
2.3 HotSpot簡介 17
2.4 JVM內存管理 19
2.5 線程和Java內存模型 20
2.6 認識不同的JVM 20
2.7 JVM的監控和工具 22
2.8 小結 25
第 3 章 硬件與操作系統 26
3.1 現代硬件簡介 27
3.2 內存 27
3.3 現代處理器特性 33
3.3.1 翻譯後備緩沖器 33
3.3.2 分支預測和推測執行 33
3.3.3 硬件存儲器模型 33
3.4 操作系統 34
3.4.1 調度器 35
3.4.2 時間問題 36
3.4.3 上下文切換 37
3.5 一個簡單的系統模型 38
3.6 基本探測策略 39
3.6.1 利用CPU 40
3.6.2 垃圾收集 41
3.6.3 I/O 42
3.6.4 機械共鳴 43
3.7 虛擬化 44
3.8 JVM和操作系統 45
3.9 小結 46
第 4 章 性能測試模式與反模式 47
4.1 性能測試的類型 47
4.1.1 延遲測試 48
4.1.2 吞吐量測試 48
4.1.3 負載測試 49
4.1.4 壓力測試 49
4.1.5 耐久性測試 49
4.1.6 容量規劃測試 49
4.1.7 退化測試 50
4.2 最佳實踐入門 50
4.2.1 自上而下的性能測試 50
4.2.2 創建一個測試環境 51
4.2.3 確定性能要求 52
4.2.4 Java特有的問題 52
4.2.5 將性能測試當作軟件開發生命周期的一部分 52
4.3 性能反模式 53
4.3.1 厭倦 53
4.3.2 填充簡歷 54
4.3.3 同儕壓力 54
4.3.4 缺乏理解 54
4.3.5 被錯誤理解的問題/不存在的問題 54
4.4 性能反模式目錄 55
4.4.1 被熱門技術分心 55
4.4.2 被簡單分心 55
4.4.3 性能調優天才 56
4.4.4 按照坊間傳說調優 57
4.4.5 把責任歸咎給驢 58
4.4.6 忽略大局 59
4.4.7 用戶驗收測試環境就是我的電腦 60
4.4.8 類似生產環境的數據很難表示 61
4.5 認知偏差與性能測試 62
4.5.1 還原論思維 62
4.5.2 確認偏差 63
4.5.3 戰爭的迷霧(行動偏差) 63
4.5.4 風險偏差 64
4.5.5 埃爾斯伯格悖論 64
4.6 小結 65
第 5 章 微基準測試與統計 66
5.1 Java性能測量 66
5.2 JMH 70
5.2.1 不是萬不得已,不要做微基準測試(一個真實的故事) 70
5.2.2 關於何時使用微基準測試的啟發 70
5.2.3 JMH框架 72
5.2.4 執行基準測試 73
5.3 JVM性能統計 77
5.3.1 誤差類型 78
5.3.2 非正態統計 82
5.4 統計的解釋 85
5.5 小結 88
第 6 章 理解垃圾收集 89
6.1 標記和清除 90
6.2 HotSpot運行時 92
6.2.1 對象的運行時表示 92
6.2.2 GC根和Arena 95
6.3 分配與生命周期 96
6.4 HotSpot中的垃圾收集 98
6.4.1 線程本地分配 98
6.4.2 半空間收集 99
6.5 並行收集器 100
6.5.1 新生代並行收集 101
6.5.2 老年代並行收集 102
6.5.3 並行收集器的局限性 103
6.6 分配的作用 104
6.7 小結 108
第 7 章 垃圾收集高級話題 109
7.1 權衡與可插拔的收集器 109
7.2 並發垃圾收集理論 111
7.2.1 JVM安全點 111
7.2.2 三色標記 112
7.3 CMS 114
7.3.1 CMS是如何工作的 115
7.3.2 用於CMS的基本JVM標志 117
7.4 G1 118
7.4.1 G1堆佈局和區域 118
7.4.2 G1算法設計 119
7.4.3 G1的各階段 120
7.4.4 用於G1的基本JVM標志 121
7.5 Shenandoah 121
7.5.1 並發壓縮 123
7.5.2 獲取Shenandoah 123
7.6 C4(Azul Zing) 124
7.7 IBM J9中的均衡收集器 127
7.7.1 J9對象頭 128
7.7.2 Balanced收集器的大數組 129
7.7.3 NUMA和Balanced收集器 129
7.8 遺留的HotSpot收集器 130
7.8.1 Serial和SerialOld 130
7.8.2 增量式CMS 131
7.8.3 已被廢棄和刪除的垃圾收集組合 131
7.8.4 Epsilon 131
7.9 小結 132
第 8 章 垃圾收集日誌、監控、調優及工具 133
8.1 認識垃圾收集日誌 133
8.1.1 開啟垃圾收集日誌記錄 133
8.1.2 垃圾收集日誌與JMX的對比 134
8.1.3 JMX的缺點 135
8.1.4 垃圾收集日誌數據帶來的好處 136
8.2 日誌解析工具 136
8.2.1 Censum 137
8.2.2 GCViewer 139
8.2.3 對於同一數據的不同可視化效果 140
8.3 基本垃圾收集調優 141
8.3.1 理解分配行為 142
8.3.2 理解暫停時間 144
8.3.3 收集器線程和GC根 145
8.4 調優Parallel GC 147
8.5 調優CMS 148
8.6 調優G1 150
8.7 jHiccup 152
8.8 小結 154
第 9 章 JVM上的代碼執行 155
9.1 字節碼解釋概覽 155
9.1.1 JVM字節碼 158
9.1.2 簡單解釋器 163
9.1.3 HotSpot特定細節 165
9.2 AOT編譯和JIT編譯 166
9.2.1 AOT編譯 166
9.2.2 JIT編譯 167
9.2.3 比較AOT和JIT 168
9.3 HotSpot JIT基礎 168
9.3.1 Klass字、虛函數表和指針變換 168
9.3.2 JIT編譯日誌 169
9.3.3 HotSpot中的編譯器 171
9.3.4 HotSpot中的分層編譯 171
9.4 代碼緩存 172
9.5 簡單JIT調優 173
9.6 小結 174
第 10 章 理解即時編譯 175
10.1 認識JITWatch 175
10.1.1 基本的JITWatch視圖 176
10.1.2 調試JVM和hsdi 180
10.2 介紹JIT編譯 180
10.3 內聯 181
10.3.1 內聯的限制 182
10.3.2 調優內聯子系統 183
10.4 循環展開 184
10.5 逃逸分析 186
10.5.1 消除堆分配 187
10.5.2 鎖與逃逸分析 188
10.5.3 逃逸分析的限制 189
10.6 單態分派 192
10.7 內部函數 195
10.8 棧上替換 197
10.9 再談安全點 199
10.10 核心庫方法 199
10.10.1 內聯方法的大小上限 199
10.10.2 編譯方法的大小上限 203
10.11 小結 204
第 11 章 Java語言性能技術 205
11.1 優化集合 206
11.2 針對列表的優化考慮 207
11.2.1 ArrayList 207
11.2.2 LinkedList 208
11.2.3 ArrayList與LinkedList的對比 209
11.3 針對映射的優化考慮 210
11.3.1 HashMap 210
11.3.2 TreeMap 212
11.3.3 缺少MultiMap 213
11.4 針對集的優化考慮 213
11.5 領域對象 213
11.6 避免終結化 216
11.6.1 血淚史:忘記清理 217
11.6.2 為什麽不使用終結化來解決這個問題 217
11.6.3 try-with-resources 219
11.7 方法句柄 223
11.8 小結 226
第 12 章 並發性能技術 227
12.1 並行介紹 228
12.2 理解JMM 232
12.3 構建並發庫 236
12.3.1 Unsafe 237
12.3.2 原子與CAS 238
12.3.3 鎖和自旋鎖 239
12.4 並發庫總結 240
12.4.1 java.util.concurrent中的Lock 240
12.4.2 讀/ 寫鎖 241
12.4.3 信號量 242
12.4.4 並發集合 242
12.4.5 鎖存器和屏障 243
12.5 執行器和任務抽象 245
12.5.1 認識異步執行 245
12.5.2 選擇一個ExecutorService 246
12.5.3 Fork/Join 246
12.6 現代Java並發 248
12.6.1 流和並行流 248
12.6.2 無鎖技術 249
12.6.3 基於Actor的技術 250
12.7 小結 251
第 13 章 剖析 252
13.1 認識剖析 252
13.2 採樣與安全點偏差 253
13.3 面向開發人員的執行剖析工具 255
13.3.1 VisualVM剖析器 255
13.3.2 JProfiler 256
13.3.3 YourKit 261
13.3.4 Java Flight Recorder和Java Mission Control 262
13.3.5 運維工具 266
13.4 現代剖析器 269
13.5 分配剖析器 272
13.6 堆轉儲分析 278
13.7 小結 280
第 14 章 高性能日誌和消息系統 281
14.1 日誌 282
14.2 設計一個影響較低的日誌記錄器 284
14.3 使用Real Logic庫實現低延遲 286
14.3.1 Agrona 287
14.3.2 Simple Binary Encoding 291
14.3.3 Aeron 294
14.3.4 Aeron的設計 296
14.4 小結 299
第 15 章 Java 9以及Java的未來方向 300
15.1 Java 9中小的性能增強 301
15.1.1 分段式代碼緩存 301
15.1.2 緊湊的字符串 301
15.1.3 新的字符串連接 302
15.1.4 C2編譯器的改進 303
15.1.5 新版G1收集器 304
15.2 Java 10和未來版本 305
15.2.1 新的發布流程 305
15.2.2 Java 10 305
15.3 Java 9及更高版本中的Unsafe 307
15.4 Valhalla項目和值類型 308
15.5 Graal和Truffle 312
15.6 字節碼的未來方向 313
15.7 並發的未來方向 315
15.8 總結 316
作者介紹 318
封面介紹 318