內容簡介
本書從實驗科學的角度探討了Java性能最佳化的方方面面,重點闡述了**的實用JVM性能調優策略、工具和技巧。通過本書,我們不僅可以了解Java原理和技術如何充分利用現代硬體和作業系統、衡量Java性能的陷阱以及微基準測試的弊端有哪些,還能深入研究可能使團隊煩惱的幾種性能測試和常見反模式、JVM垃圾收集、JIT編譯和Java語言性能技術等。本書為讀者打開了深入理解Java性能的大門,並以路標助力其最佳化之旅。
圖書目錄
中文版推薦序一 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