本書以Java性能調(diào)優(yōu)為主線,系統(tǒng)地闡述了與Java性能優(yōu)化相關(guān)的知識與技巧。本書共6章,先后從軟件設(shè)計、軟件編碼、JVM調(diào)優(yōu)及程序故障排除等方面介紹針對Java程序的優(yōu)化方法。第1章介紹性能的基本概念、木桶原理與Amdahl定律、系統(tǒng)調(diào)優(yōu)的過程和注意事項;第2章從設(shè)計層面介紹與性能相關(guān)的設(shè)計模式及常用優(yōu)化組件;第3章從代碼層面介紹如何編寫高性能的Java程序;第4章介紹并進行開發(fā)和如何通過多線程提高系統(tǒng)性能;第5章立足于JVM虛擬機層面,介紹如何通過設(shè)置合理的JVM參數(shù)提升Java程序的性能;第6章為工具篇,介紹了獲取和監(jiān)控程序或系統(tǒng)性能指標的各種工具,包括相關(guān)的故障排查工具。本書適合所有Java程序員、軟件設(shè)計師、架構(gòu)師及軟件開發(fā)愛好者,對于有一定經(jīng)驗的Java工程師,本書更能幫助他突破技術(shù)瓶頸,深入Java內(nèi)核開發(fā)!
前言
第1章 Java性能調(diào)優(yōu)概述1
1.1 性能概述1
1.1.1 看懂程序的性能1
1.1.2 性能的參考指標2
1.1.3 木桶原理與性能瓶頸2
1.1.4 Amdahl定律3
1.2 性能調(diào)優(yōu)的層次5
1.2.1 設(shè)計調(diào)優(yōu)5
1.2.2 代碼調(diào)優(yōu)6
1.2.3 JVM調(diào)優(yōu)6
1.2.4 數(shù)據(jù)庫調(diào)優(yōu)6
1.2.5 操作系統(tǒng)調(diào)優(yōu)7
1.3 基本調(diào)優(yōu)策略和手段7
1.3.1 優(yōu)化的一般步驟8
1.3.2 系統(tǒng)優(yōu)化的注意事項8
1.4 小結(jié)9
第2章 設(shè)計優(yōu)化10
2.1 善用設(shè)計模式10
2.1.1 單例模式10
2.1.2 代理模式15
2.1.3 享元模式24
2.1.4 裝飾者模式28
2.1.5 觀察者模式34
2.1.6 值對象模式38
2.1.7 業(yè)務(wù)代理模式41
2.2 常用的優(yōu)化組件和方法44
2.2.1 緩沖44
2.2.2 緩存47
2.2.3 對象復(fù)用——池51
2.2.4 并行替代串行58
2.2.5 負載均衡58
2.2.6 時間換空間63
2.2.7 空間換時間64
2.3 小結(jié)66
第3章 Java程序優(yōu)化67
3.1 字符串優(yōu)化處理67
3.1.1 String對象及其特點67
3.1.2 substring()方法的內(nèi)存泄漏69
3.1.3 字符串分割和查找72
3.1.4 StringBuffer和StringBuilder76
3.1.5 CompactStrings優(yōu)化字符串存儲80
3.2 核心數(shù)據(jù)結(jié)構(gòu)81
3.2.1 List接口81
3.2.2 Map接口88
3.2.3 Set接口100
3.2.4 優(yōu)化集合訪問代碼101
3.2.5 RandomAccess接口103
3.3 使用NIO提升性能105
3.3.1 NIO中的Buffer類族和Channel106
3.3.2 Buffer的基本原理107
3.3.3 Buffer的相關(guān)操作109
3.3.4 MappedByteBuffer性能評估116
3.3.5 直接訪問內(nèi)存119
3.4 引用類型121
3.4.1 強引用121
3.4.2 軟引用122
3.4.3 弱引用123
3.4.4 虛引用124
3.4.5 WeakHashMap類及其實現(xiàn)127
3.5 性能測試工具JMH129
3.5.1 JMH之Hello World130
3.5.2 JMH之指定測量模式131
3.5.3 JMH之對象作用域134
3.5.4 JMH之代碼消除135
3.6 有助于改善性能的技巧137
3.6.1 使用局部變量137
3.6.2 位運算代替乘除法138
3.6.3 替換switch139
3.6.4 一維數(shù)組代替二維數(shù)組141
3.6.5 提取表達式142
3.6.6 展開循環(huán)143
3.6.7 布爾運算代替位運算144
3.6.8 使用arrayCopy()145
3.6.9 使用Buffer進行I/O操作147
3.6.10 使用clone()代替new149
3.6.11 慎用Java函數(shù)式編程151
3.7 小結(jié)152
第4章 并行程序開發(fā)及優(yōu)化153
4.1 并行程序設(shè)計模式153
4.1.1 Future模式153
4.1.2 Master-Worker模式161
4.1.3 Guarded Suspension模式165
4.1.4 不變模式172
4.1.5 生產(chǎn)者-消費者模式174
4.2 JDK多任務(wù)執(zhí)行框架178
4.2.1 無限制線程的缺陷178
4.2.2 簡單的線程池實現(xiàn)179
4.2.3 Executor框架183
4.2.4 自定義線程池185
4.2.5 優(yōu)化線程池大小189
4.2.6 擴展ThreadPoolExecutor189
4.3 JDK并發(fā)數(shù)據(jù)結(jié)構(gòu)191
4.3.1 并發(fā)List191
4.3.2 并發(fā)Set193
4.3.3 并發(fā)Map194
4.3.4 并發(fā)Queue195
4.3.5 并發(fā)Deque197
4.4 并發(fā)控制方法199
4.4.1 Java內(nèi)存模型與volatile199
4.4.2 同步關(guān)鍵字synchronized203
4.4.3 重入鎖205
4.4.4 讀寫鎖207
4.4.5 讀寫鎖的改進:StampedLock209
4.4.6 Condition對象210
4.4.7 信號量212
4.4.8 線程局部變量ThreadLocal214
4.5 鎖的性能和優(yōu)化215
4.5.1 線程的開銷215
4.5.2 避免死鎖215
4.5.3 減少鎖持有時間219
4.5.4 減小鎖粒度220
4.5.5 讀寫分離鎖來替換獨占鎖221
4.5.6 鎖分離222
4.5.7 重入鎖和內(nèi)部鎖224
4.5.8 鎖粗化224
4.5.9 自旋鎖226
4.5.10 鎖消除226
4.5.11 鎖偏向227
4.6 無鎖的并行計算228
4.6.1 非阻塞的同步/無鎖228
4.6.2 原子操作228
4.6.3 Amino框架簡介231
4.6.4 Amino集合231
4.6.5 Amino樹236
4.6.6 Amino圖237
4.6.7 Amino簡單調(diào)度模式238
4.7 協(xié)程240
4.7.1 協(xié)程的概念240
4.7.2 Kilim框架簡介241
4.7.3 Task及其狀態(tài)242
4.7.4 Fiber及其狀態(tài)242
4.7.5 Kilim開發(fā)環(huán)境配置243
4.7.6 Kilim之Hello World244
4.7.7 多任務(wù)通信246
4.7.8 Kilim實例及性能評估247
4.8 小結(jié)250
第5章 JVM調(diào)優(yōu)251
5.1 Java虛擬機內(nèi)存模型251
5.1.1 程序計數(shù)器251
5.1.2 Java虛擬機棧252
5.1.3 本地方法棧258
5.1.4 Java堆258
5.1.5 方法區(qū)260
5.2 JVM內(nèi)存分配參數(shù)263
5.2.1 設(shè)置最大堆內(nèi)存264
5.2.2 設(shè)置最小堆內(nèi)存264
5.2.3 設(shè)置新生代266
5.2.4 設(shè)置持久代266
5.2.5 設(shè)置線程棧267
5.2.6 堆的比例分配269
5.2.7 堆分配參數(shù)總結(jié)270
5.3 垃圾收集基礎(chǔ)271
5.3.1 垃圾收集的作用272
5.3.2 垃圾回收算法與思想272
5.3.3 垃圾回收器的類型277
5.3.4 評價GC策略的指標278
5.3.5 新生代串行回收器278
5.3.6 老年代串行回收器279
5.3.7 并行回收器280
5.3.8 新生代并行回收器281
5.3.9 老年代并行回收器282
5.3.10 CMS回收器282
5.3.11 G1回收器285
5.3.12 Stop the World案例286
5.3.13 垃圾回收器對系統(tǒng)性能的影響288
5.3.14 GC操作相關(guān)參數(shù)總結(jié)289
5.4 常用調(diào)優(yōu)案例和方法291
5.4.1 將新對象預(yù)留在新生代291
5.4.2 大對象進入老年代294
5.4.3 設(shè)置對象進入老年代的年齡296
5.4.4 穩(wěn)定與振蕩的堆大小296
5.4.5 吞吐量優(yōu)先案例298
5.4.6 使用大頁案例298
5.4.7 降低停頓案例299
5.5 實用JVM參數(shù)299
5.5.1 JIT編譯參數(shù)299
5.5.2 堆快照301
5.5.3 錯誤處理302
5.5.4 獲取GC信息302
5.5.5 類和對象跟蹤304
5.5.6 控制GC305
5.5.7 選擇類校驗器305
5.5.8 Solaris下的線程控制306
5.5.9 使用大頁306
5.5.10 壓縮指針306
5.6 JVM調(diào)優(yōu)實戰(zhàn)306
5.6.1 Tomcat簡介與啟動加速307
5.6.2 Web應(yīng)用程序簡介309
5.6.3 JMeter簡介與使用310
5.6.4 調(diào)優(yōu)前Web應(yīng)用運行狀況313
5.6.5 調(diào)優(yōu)過程314
5.7 小結(jié)315
第6章 Java性能調(diào)優(yōu)工具316
6.1 Linux命令行工具316
6.1.1 top命令316
6.1.2 sar命令318
6.1.3 vmstat命令319
6.1.4 iostat命令321
6.1.5 pidstat工具322
6.2 Windows工具326
6.2.1 任務(wù)管理器326
6.2.2 perfmon性能監(jiān)控工具328
6.2.3 Process Explorer工具331
6.2.4 pslist命令行333
6.3 JDK命令行工具334
6.3.1 jps命令335
6.3.2 jstat命令336
6.3.3 jinfo命令339
6.3.4 jmap命令340
6.3.5 jhat命令341
6.3.6 jstack命令343
6.3.7 jstatd命令346
6.3.8 hprof工具347
6.3.9 jcmd命令349
6.4 JConsole工具350
6.4.1 JConsole連接Java程序350
6.4.2 Java程序概況351
6.4.3 內(nèi)存監(jiān)控352
6.4.4 線程監(jiān)控352
6.4.5 類加載情況354
6.4.6 虛擬機信息354
6.4.7 MBean管理355
6.4.8 使用插件356
6.5 Visual VM多合一工具357
6.5.1 Visual VM連接應(yīng)用程序358
6.5.2 監(jiān)控應(yīng)用程序概況359
6.5.3 Thread Dump和分析361
6.5.4 性能分析362
6.5.5 快照365
6.5.6 內(nèi)存快照分析365
6.5.7 MBean管理功能367
6.5.8 TDA的使用367
6.5.9 BTrace簡介368
6.6 Visual VM對OQL的支持374
6.6.1 Visual VM的OQL基本語法374
6.6.2 內(nèi)置heap對象375
6.6.3 對象函數(shù)376
6.6.4 集合/統(tǒng)計函數(shù)380
6.6.5 程序化OQL384
6.7 MAT內(nèi)存分析工具386
6.7.1 初識MAT386
6.7.2 淺堆和深堆389
6.7.3 支配樹392
6.7.4 垃圾回收根394
6.7.5 內(nèi)存泄漏檢測395
6.7.6 最大對象報告396
6.7.7 查找支配者396
6.7.8 線程分析397
6.7.9 集合使用情況分析398
6.7.10 擴展MAT399
6.8 MAT對OQL的支持403
6.8.1 Select子句404
6.8.2 From子句406
6.8.3 Where子句407
6.8.4 內(nèi)置對象與方法408
6.9 來自JRockit的禮物——JMC411
6.9.1 得到JFR文件412
6.9.2 Java程序的整體運行情況413
6.9.3 CPU分析413
6.9.4 內(nèi)存分析414
6.9.5 I/O分析416
6.10 小結(jié)418