本書從JVM和Java API兩個方面,深入地介紹了Java 8和Java 11等新的Java長期支持版本中影響性能的因素。本書先從Java應(yīng)用程序的通用方法、基準(zhǔn)測試的缺陷、性能監(jiān)控工具等方面,分析了如何通過JVM的配置方式影響程序的性能;接著從即時編譯、垃圾回收、堆內(nèi)存與原生內(nèi)存最佳實踐、線程與同步的性能等方面,分析了常見的優(yōu)化方向及其特性。第2版專注于更加成熟的Java 8和Java 11,主要的更新內(nèi)容涉及G1垃圾回收器和Java飛行記錄器,以及Java在容器化環(huán)境下的性能變化。
Java性能優(yōu)化越來越難。曾經(jīng),通過引入即時編譯器,能實現(xiàn)8倍的性能飛躍。而今,你可能會有疑問:Java性能還有多大的優(yōu)化空間?本書直面這一問題,證明對于工程師而言,仍有很多工作可做!
1.業(yè)內(nèi)老牌工程師編著,資歷深厚眼光毒辣
本書作者從事Oracle云平臺軟件的性能優(yōu)化工作。在加入Oracle之前,他是Sun公司的Java布道師,并在2001年加入Java性能工程小組。作為業(yè)內(nèi)深耕多年的老牌工程師,他將自己多年的JAVA編程經(jīng)驗整合在書中,透徹解釋了JVM和Java平臺特性對應(yīng)用程序性能的影響。
2.拒絕“治標(biāo)不治本”
本書幫助你針對Java 8和Java 11的性能優(yōu)化措施、工具和方法,從根本上理解應(yīng)用程序性能欠佳的原因,并熟練地運用恰當(dāng)?shù)臉?biāo)志提升性能,隨書附贈JVM調(diào)優(yōu)標(biāo)志速查表,含80余個常用調(diào)優(yōu)標(biāo)志
,讓你不再盲目測試數(shù)以百計的Java標(biāo)志效果。
3.更新內(nèi)容,更新體驗
本書相對于前書而言,專注于更加成熟的Java 8和Java 11,主要更新內(nèi)容包括Java平臺新特性(新型微基準(zhǔn)測試工具、新的即時編譯器、新的性能工具等)、Java 11新特性(緊湊字符串和字符串連接的增強等),也涉及到了GI垃圾回收器和Java飛行記錄器,以及Java在容器化環(huán)境中運行方式的變化。
4.實用代碼資源隨書贈
本書附贈示例代碼資源,更將新的術(shù)語與重點強調(diào)內(nèi)容黑體劃重點,不同代碼以不同的字體排版展示,一目了然方便區(qū)分,閱讀學(xué)習(xí)更簡單。
本書內(nèi)容要點:
* 理解Java平臺特性和編譯器如何影響性能
* 掌握Java垃圾回收機制
* 通過遵循4項原則來優(yōu)化性能測試結(jié)果
* 使用JDK等工具了解Java應(yīng)用程序的性能情況
* 通過編程實踐來盡量降低垃圾回收器的不良影響
* 解決Java API的各種性能難題
* 改善數(shù)據(jù)庫應(yīng)用程序的性能
【作者簡介】
斯科特·奧克斯(Scott Oaks)
Oracle公司架構(gòu)師,從事Oracle云平臺軟件的性能優(yōu)化工作。在加入Oracle之前,他是Sun公司的Java布道師,并在2001年加入Java性能工程小組,專注于Java的性能優(yōu)化工作。除了本書,他還著有多部涉及Java線程、Java安全等方面的著作。
【譯者簡介】
黨文亮
沉浸Java相關(guān)領(lǐng)域多年,目前在華為云專注于性能診斷平臺和OS管理系統(tǒng)的研發(fā),有大量從0到1的項目實踐經(jīng)驗,在逆向、性能、算法等方面都有一定的積累。
前言 xiii
第 1章 導(dǎo)論 1
1.1 概述 2
1.2 平臺和約定 2
1.2.1 Java平臺 2
1.2.2 硬件平臺 4
1.3 全面的性能 6
1.3.1 寫出更好的算法 6
1.3.2 寫更少的代碼 7
1.3.3 過早優(yōu)化 8
1.3.4 其他:數(shù)據(jù)庫永遠是瓶頸 9
1.3.5 常見優(yōu)化 9
1.4 小結(jié) 10
第 2章 性能測試方法 11
2.1 測試真實的應(yīng)用程序 11
2.1.1 微基準(zhǔn)測試 11
2.1.2 宏基準(zhǔn)測試 15
2.1.3 介基準(zhǔn)測試 16
2.2 理解吞吐量、批處理時間和響應(yīng)時間 17
2.2.1 測量批處理時間17
2.2.2 測量吞吐量18
2.2.3 測量響應(yīng)時間 19
2.3 理解可變性22
2.4 早測試、常測試 25
2.5 基準(zhǔn)測試示例 27
2.5.1 Java 微基準(zhǔn)測試工具 27
2.5.2 常用代碼示例 34
2.6 小結(jié) 36
第3 章 Java 性能工具箱 38
3.1 操作系統(tǒng)工具和分析 38
3.1.1 CPU 使用率 39
3.1.2 CPU 運行隊列 41
3.1.3 磁盤使用率 42
3.1.4 網(wǎng)絡(luò)使用率 44
3.2 Java 監(jiān)控工具 45
3.2.1 基本的VM 信息 46
3.2.2 線程信息 48
3.2.3 類信息 49
3.2.4 實時GC 分析 49
3.2.5 堆轉(zhuǎn)儲后期處理 49
3.3 性能分析工具 49
3.3.1 采樣分析器 50
3.3.2 探查分析器 53
3.3.3 阻塞方法和線程時間線 54
3.3.4 原生分析器 55
3.4 JFR 57
3.4.1 Java Mission Control 57
3.4.2 JFR 概覽 58
3.4.3 開啟JFR 64
3.4.4 選擇JFR 事件 67
3.5 小結(jié) 69
第4 章 使用即時編譯器 70
4.1 即時編譯器:概覽 70
4.2 分層編譯 73
4.3 常用的編譯器標(biāo)志 74
4.3.1 優(yōu)化代碼緩存 74
4.3.2 檢查編譯過程 75
4.3.3 分層編譯級別 78
4.3.4 逆優(yōu)化 79
4.4 高級編譯器標(biāo)志 82
4.4.1 編譯閾值 82
4.4.2 編譯線程 83
4.4.3 內(nèi)聯(lián) 85
4.4.4 逃逸分析 86
4.4.5 CPU 相關(guān)代碼 87
4.5 分層編譯的權(quán)衡 88
4.6 GraalVM 89
4.7 預(yù)編譯 90
4.7.1 提前編譯 90
4.7.2 GraalVM 原生編譯 92
4.8 小結(jié) 93
第5 章 垃圾回收簡介 95
5.1 垃圾回收概覽 95
5.1.1 分代垃圾回收器97
5.1.2 GC 算法99
5.1.3 選擇GC 算法101
5.2 GC 優(yōu)化基礎(chǔ)108
5.2.1 調(diào)整堆的大小 108
5.2.2 調(diào)整分代大小 110
5.2.3 調(diào)整元空間大小 112
5.2.4 控制并行113
5.3 GC 工具114
5.3.1 在JDK 8 中開啟GC 日志 114
5.3.2 在JDK 11 中開啟GC 日志 115
5.4 小結(jié) 118
第6 章 垃圾回收算法 119
6.1 理解Throughput 回收器 119
6.2 理解G1 垃圾回收器 125
6.3 理解CMS 回收器 136
6.4 高級優(yōu)化 143
6.4.1 晉升和Survivor 空間143
6.4.2 分配大對象 146
6.4.3 AggressiveHeap 標(biāo)志 152
6.4.4 完全掌控堆的大小 153
6.5 實驗性GC 算法 154
6.5.1 并發(fā)壓縮:ZGC 和Shenandoah 154
6.5.2 無回收:Epsilon GC 156
6.6 小結(jié)157
第7 章 堆內(nèi)存最佳實踐 159
7.1 堆分析 159
7.1.1 堆直方圖160
7.1.2 堆轉(zhuǎn)儲161
7.1.3 內(nèi)存溢出錯誤 164
7.2 減少內(nèi)存使用 168
7.2.1 減小對象大小 169
7.2.2 使用延遲初始化171
7.2.3 使用不可變對象和標(biāo)準(zhǔn)化對象 175
7.3 對象生命周期管理 176
7.3.1 對象重用177
7.3.2 軟引用、弱引用和其他引用181
7.3.3 壓縮的普通對象指針193
7.4 小結(jié)194
第8 章 原生內(nèi)存最佳實踐195
8.1 內(nèi)存占用195
8.1.1 測量內(nèi)存占用 196
8.1.2 最小化內(nèi)存占用197
8.1.3 原生內(nèi)存跟蹤 197
8.1.4 共享庫原生內(nèi)存201
8.2 針對操作系統(tǒng)的JVM 優(yōu)化 204
8.3 小結(jié)208
第9 章 線程和同步性能 209
9.1 線程和硬件209
9.2 線程池和ThreadPoolExecutor 210
9.2.1 設(shè)置最大線程數(shù)210
9.2.2 設(shè)置最小線程數(shù)213
9.2.3 線程池任務(wù)大小215
9.2.4 設(shè)置ThreadPoolExecutor 的大小215
9.3 ForkJoinPool.217
9.3.1 工作竊取 221
9.3.2 自動并行化 223
9.4 線程同步 224
9.4.1 同步的代價 225
9.4.2 避免同步 228
9.4.3 偽共享 230
9.5 JVM 線程優(yōu)化 233
9.5.1 優(yōu)化線程棧大小 234
9.5.2 偏向鎖234
9.5.3 線程優(yōu)先級 235
9.6 監(jiān)控線程和鎖 235
9.6.1 查看線程235
9.6.2 查看阻塞線程 236
9.7 小結(jié)239
第 10 章 Java 服務(wù)器 240
10.1 Java NIO 概覽 240
10.2 服務(wù)器容器 242
10.2.1 優(yōu)化服務(wù)器線程池 242
10.2.2 異步Rest 服務(wù)器 243
10.3 異步出站調(diào)用246
10.4 JSON 處理251
10.4.1 解析和編組概覽 252
10.4.2 JSON 對象 253
10.4.3 JSON 解析 254
10.5 小結(jié) 256
第 11 章 數(shù)據(jù)庫性能最佳實踐 257
11.1 示例數(shù)據(jù)庫 258
11.2 JDBC 258
11.2.1 JDBC 驅(qū)動 258
11.2.2 JDBC 連接池 260
11.2.3 預(yù)處理語句和語句池 261
11.2.4 事務(wù) 262
11.2.5 結(jié)果集處理269
11.3 JPA270
11.3.1 優(yōu)化JPA 寫 271
11.3.2 優(yōu)化JPA 讀 272
11.3.3 JPA 緩存 275
11.4 Spring Data280
11.5 小結(jié)281
第 12 章 Java SE API 技巧282
12.1 字符串 282
12.1.1 壓縮字符串 282
12.1.2 重復(fù)字符串和字符串保留283
12.1.3 字符串連接 288
12.2 緩沖I/O 291
12.3 類加載 293
12.4 隨機數(shù) 296
12.5 Java 原生接口298
12.6 異常300
12.7 日志303
12.8 Java 集合API304
12.8.1 同步和非同步305
12.8.2 設(shè)置集合大小306
12.8.3 集合與內(nèi)存效率 307
12.9 Lambda 和匿名類 308
12.10 流和過濾器的性能310
12.11 對象序列化 312
12.11.1 瞬時字段312
12.11.2 覆蓋默認的序列化313
12.11.3 壓縮序列化數(shù)據(jù) 315
12.11.4 跟蹤重復(fù)對象317
12.12 小結(jié) 319
附錄 調(diào)優(yōu)標(biāo)志總結(jié) 321