本書主要展示了如何在當今先進的多核硬件和復雜的操作系統環境下,系統且主動地提高Java 性能。本書對Charlie Hunt 和Binu John 的經典圖書Java Performance 進行延伸,提供了兩個前所未有的、強大的Java 平臺創新細節:Garbage First(G1)垃圾收集器和HotSpot 虛擬機服務代理。閱讀本書,你就可以在任何情況下從JDK8 或9 中發揮Java 的*性能。
本書作者是Java性能和Java HotSpot 虛擬機領域的佼佼者,幫助你利用現代軟工實踐提高性能,避免常見錯誤,從實戰生涯中總結技巧和竅門。
利用G1克服并行、串行和CMS垃圾收集器的局限性了解G1 GC收集的各個階段,包括年輕代和老年代在G1的引擎下微調您的應用程序確定潛在優化方案,解釋實驗結果,并付諸行動探索的HotSpot虛擬機內部使用熱點VM服務代理分析、分流,并解決不同的熱點
推薦序1
若干年前,Charlie Hunt出過一本Java之父Gosling欣然作序推薦的Java TM
Performance,我現在還記得推薦語中那些星光熠熠的名字Azul的R大莫樞,阿里花名叫畢玄的林昊,《深入理解Java虛擬機》的作者周志明等等。
若干年后,Charlie Hunt又出了它的姊妹篇Java Performance Companion(中文書名為《Java性能調優指南》)。 這次輪到我被春雨邀來作序,深感榮幸。
與前一本大而全的Java調優圣經相比,這本薄薄的姊妹篇只深入講解了兩件事情:一是很多人知道但并不太精通的G1垃圾收集算法,另一個是JDK自帶的,強大但鮮有人知,面試里問誰誰死的工具HotSpot Serviceability Agent。為什么要單挑這兩點來出一本書呢,大概是作者覺得一線的Java性能調優工程師以及負責Trouble Shooting的大神,都需要掌握這些細節,而目前已有的書籍和文章,又達不到作者期望的深度吧。
與Java程序員相依相伴了很多年的CMS垃圾收集算法,隨著現在Java應用的內存越占越大的情況,在暫停時間上有點力不從心了。但壓測的經歷告訴我們,不是簡單地把算法改成G1就可以。從十年前G1理論的提出,到在JDK8里真正可用,JVM的工程師們反復打磨了漫長的時光,可見其實現是相當復雜的。如果真的在生產環境對延時敏感嚴苛的應用上使用它,你需要了解更多的實現細節,更多的優化技巧,才能有足夠的信心去把控未來可能出現的情況本書正好提供了這方面的內容。
而另一個SA就更好玩了。大部分負責火線處理狀況的工程師都會用Thread Dump、 Heap Dump 、BTrace來獲取JVM和應用的狀態,偶然間,我也在R大指導下,用過gdb來查找線程死鎖的原因。其實,JDK還為這些苦惱的救火員們,準備了另一份強大的分析工具SA及其可視化的工具HSDB。可惜搜遍互聯網,也就只有R大寫過一篇介紹,還有寒泉子和占小狼寫過使用的案例。希望憑這本書,能多制造出幾個在自己公司里充當定海神針的大神來。
如果我沒有加入唯品會的基礎架構部,也不會每天睜眼就面對各種服務調用超時、GC暫停、并發鎖或其他不可描述的奇怪狀況,也不會獲得如此多的鍛煉和感悟。我有感于此,希望有更多的Java程序員,在業務代碼開發之外,永遠對性能優化,對優雅代碼,保持自己的欲望;對各種意外情況,保持好奇心而不是恐懼感。最后做個廣告(嗯,俠少答應的寫序的福利),我的所有這些Java工作的日常與思考,都會寫在個人微信號春天的旁邊里,歡迎來訪。
肖樺(江南白衣)
唯品會高級架構師
推薦序2
俠少邀請我為本書寫序已經挺久了,直到2017年春節假期之后才開始動筆,再拖都有點過意不去了,在此還是要感謝下俠少及博文視點對我的信任和包容。
本序主要分為兩部分,一部分是對本書的內容做一個大致的介紹,另外一部分是簡述下本人走上JVM這條路的心路歷程。
收到本書樣稿之后滿懷期待地看了起來,當我第一次看到目錄時還是震驚了一下,因為本書的重點在G1 GC和SA,兩者實際上并沒有多大關系,將它們倆合在一起寫成此書,本人覺得挺新鮮的,而且本書有且僅有這兩者,不過再想想這本書的名字,其實也合情合理。
G1 GC是HotSpot重點發展的GC算法,和其他GC算法最大的區別是弱化了分代的概念,引入了分區的思想,從JDK8開始算比較穩定了,官方也推薦大家使用G1 GC來替代CMS GC,是未來大家首選的GC算法。盡管G1希望能做到自適應,但是畢竟每個系統的特性不一樣,最終可能仍然省不了參數調優的活,本書從實現的角度來闡述了這個算法的各個細節,另外值得一提的是,書中提到的細節完全可以映射到代碼中來一起看,它將帶您一步步揭開G1 GC的神秘面紗。另外我曾有幸和本書的作者之一Monica有過一面之緣,她談及對G1的理解還是讓我挺驚訝的。
SA作為JDK自帶的一款優秀的分析工具,本身就是用Java實現的,所以它可以讓JVM里的數據結構直接以Java的形式暴露在您面前,比如說我們方法調用會創建一個棧幀,那這個棧幀在JVM里是怎樣的結構?又比如我們想要獲取運行時加載的類的字節碼,都可以直接通過API獲取到。另外本書還介紹了一個重要的圖形化工具HSDB,它是基于SA實現的,可以讓您更直觀地看到對象在VM里的數據結構以及對象依賴和被依賴的關系等,這個工具在我們在平時查問題的時候提供了極大的便利,可以這么說吧,如果您熟悉SA的數據結構,那您對JVM的數據結構也算清晰了解了,它為我們Java開發者打開了學習JVM的另外一扇大門。
接下來說說我的經歷吧,其實我算不上JVM領域的前輩,更談不上JVM領域的精英,說是JVM領域的一個新手一點不為過。阿里是我2010年大學畢業后的第一份工作(目前我還一直在支付寶),它是一個Java王國,對Java重度依賴,然而我在進阿里之前對Java其實并沒有進行太深入的學習,可以說了解的非常少,主要技能集中在Flex/Flash/ActionScript領域,現在沒有進入前端界其實還是有點小遺憾的,因為一直都喜歡所見即所得的這種感覺。進入支付寶之后我從事的是Java框架研發的偏基礎性質的工作,一干就是三四年,非常感謝這段寶貴的經歷,讓我從前端過渡到了后端,同時讓我有足夠多的機會碰到各種中間件周邊技術的疑難雜癥,并不斷嘗試去解決他們。后面我們框架做大版本升級改造,遷移到標準的OSGI容器equniox上來,于是碰到了大量的類加載問題,譬如ClassNotFoundException、LinkageError等這些問題,如果對類加載機制不是很熟悉還是比較難解決的,我們當時僅僅對JDK層面的類加載機制熟悉,深入到JVM里的實現就完全是個黑盒了,類似LinkageError這種問題在您看了JVM里的實現之后才可能有更深的理解,就這樣一個偶然的機會開始下載OpenJDK代碼,并研究起JVM來,不過說來也奇怪,在此之后公司碰到的JVM的問題感覺也越來越多了,比如內存溢出、頻繁GC、系統卡死等。我在2014年年底的時候正式加入到了阿里JVM團隊,開始了真正的JVM探索之旅。
在探索JVM的過程中,我基本是問題驅動型的,因為我們在平時工作過程中也很容易碰到很多JVM相關的問題,通過一個個攻破這些問題從而積累了不少實踐經驗,對實現原理也慢慢地熟悉起來,針對一些比較有代表性的文章,我常常會將解決思路記錄成文保存下來,并通過個人博客(http://lovestblog.cn),個人微信公眾號(你假笨),或者阿里內部的ATA技術論壇等進行傳播,希望這些經驗能幫助到更多的人,讓他們少走彎路,更多的精力能花在他們自己的業務開發上面。
你假笨
阿里JVM專家寒泉子
譯者序
早些年用C/C 做開始時,內存管理錯誤一直是程序員們(包括我)在開發中面對的最大的困擾之一,各種內存方面的怪異問題經常把人折磨的欲仙欲死,當然我也不否認Debug過程極其有效的幫助我更深入的學習了內存管理機制。在最初轉向Java開發時,我覺得就像籠罩在頭上幾十年的霧霾一下都不見了,要對象是嗎?來吧,new一個。再也不用管要不要或什么時候free或delete。 但隨著了解的不斷深入,我們發現天底下真的沒有免費的午餐,有所得也就必有所失。在享受垃圾收集器的便利的同時,也許你就要忍受其帶來效率的降低(原因有很多,比如配置不當)。而且這些年垃圾收集的技術一直在持續發展,是否采用垃圾收集?采用何種垃圾收集?如何調優?等等。一系列的問題,慢慢成為架構設計時就要考慮的問題,而不再僅僅是自動回收內存那么簡單。于是乎,深入了解垃圾收集技術,就十分必要了。
垃圾收集技術本身不是一個新技術,各種效率方面的質疑與探討也不是什么新話題,而垃圾收集器本身也發展了一代一代又一代。但很多開發人員因為工作原因本身,停留在知其然而不知其所以然的層面上。而本書,針對Java G1垃圾收集器以及調試診斷方面,做了全面而深入的總結,而專注于G1的書籍目前幾乎是個空白,本書的出現恰好彌補了這方面的內容。本書的發起者及作者之一的Charlie Hunt,其也是Java應用性能調優圣經《Java性能優化權威指南》的作者,他曾任Oracle公司首席JVM性能工程師,負責HotSpot Java虛擬機和Java SE類庫性能的改進。而其他幾位作者同樣在G1垃圾收集器方面有非常深厚的功底和豐富的調優經驗。本書作為《Java性能優化權威指南》的姊妹篇,內容可能不如其那么豐富,但本書在G1的細節方面會更加的深入與廣泛。
作為譯者,我已經盡可能地避免錯誤和疏漏出現在譯本中,不過由于譯者本人能力有限,書中難免有些不妥之處,希望廣大讀者與同行批評指正。
最后要感謝電子工業出版社的張春雨老師與倩雪編輯,感謝他們在我翻譯過程中給予的幫助和包容。同時還要感謝家人和朋友的寶貴支持,這段時間基本處于失聯狀態,現在我胡漢三又回來啦。謝謝你們。
李源
途牛旅游網供應鏈研發中心總經理
前言
歡迎來到Java
李源,碩士,解放軍某醫院醫學信息中心工程師,從事醫學信息化工作10年,在網絡建設、軟件開發及科研方面具有豐富經驗,熟悉C#、Java、ASP.NET等多種編程語言,曾自主研制國內首套智能防倒號自助掛號系統,并獲得國家專利。
Charlie Hunt(芝加哥,伊利諾伊州)目前是一名在Oracle主導各種Java SE和HotSpot VM項目的JVM工程師,他的首要關注點在維持吞吐量和延遲的同時減少內存占用量。他也是JavaTM Performance 一書的第一作者。他是JavaOne大會的常任主持,并被公認為是Java超級明星。他同樣是很多會議的發言人,包括QCon、Velocity、GoTo和Dreamforce。Charlie之前為Oracle主導過各種Java SE和HotSpot VM項目,經歷過多個不同性能的崗位,包括在Salesforce.com擔任性能工程架構師,以及在Oracle和Sun Microsystems擔任HotSpot VM性能架構師。他在1998年寫下了他的第一個Java應用程序,在1999年作為Java高級架構師加入Sun Microsystems,從那以后一直對Java和JVM的性能抱有熱情。
Monica Beckwith是一位獨立的性能顧問,主要從事優化基于Java虛擬機的服務級系統的客戶應用程序。她過去的工作經歷包括Oracle、Sun Microsystems和AMD。Monica曾經從事用Java HotSpot VM優化JIT編譯器、生成代碼、JVM啟發式算法,以及垃圾收集和垃圾收集器方面的工作。她是許多會議上的固定發言人并多次發表主題為垃圾收集、Java內存模型等的文章。Monica領導過Oracle的G1垃圾收集器性能團隊,并被人稱為JavaOne搖滾明星。
Poonam Parhar (圣克拉拉,加利福利亞州)現在是一名在Oracle的JVM支持工程師,她的主要工作職責是解決針對JRockit和HotSpot VM的客戶升級問題。她喜歡調試和排除故障,并且一直關注著HotSpot VM適用性和可維護性的提升。她明確了HotSpot VM里很多復雜的垃圾收集問題,并且為了能更方便進行故障排除和修復垃圾收集器相關的問題,她一直致力于提升調試工具和產品可維護性。她為可適用性代理調試器做出很多貢獻,并為它開發了一個VisualVM插件。她在2011年的JavaOne會議上分享了適用于SA 的VisualVM插件。為了幫助客戶和Java社區,她通過在https://blogs.oracle.com/poonam/上維護博客來分享自己的工作經驗和知識。
Bengt Rutisson(斯德哥爾摩,瑞典)是一名Oracle的JVM工程師,他在HotSpot工程團隊工作。過去十年一直從事關于JVM里的垃圾收集器的工作,他最初接觸的是JRockit VM,隨后六年使用HotSpot VM。Bengt是OpenJDK項目中的積極參與者,在特性、穩定性修復以及性能增強方面做出了許多貢獻。
前言 VII
致謝 IX
作者介紹 XII
第1章 Garbage First綜述 1
術語 1
并行垃圾收集器 2
串行垃圾收集器 4
并發標記清除(CMS)垃圾收集器 5
收集器的概括總結 7
Garbage First(G1)垃圾收集器 8
G1設計 10
巨型(Humongous)對象 12
Full垃圾收集 12
并發周期 13
堆空間調整 13
引用 14
第2章 深入Garbage First垃圾收集器 15
背景 15
G1中的垃圾收集 16
年輕代 17
年輕代收集暫停 18
對象老化與老年代 19
巨型分區 19
混合收集 22
收集集合及其重要性 24
已記憶集合及其重要性 24
并發優化線程以及柵欄 28
G1 GC的并發標記 30
并發標記階段 34
初始標記 34
根分區掃描 34
并發標記 34
重新標記 36
清除 36
轉移失敗與Full收集 37
引用 38
第3章 Garbage First垃圾收集器性能優化 39
年輕代收集的各階段 39
所有并行活動的開始 41
外部根分區 42
已記憶集合和已處理緩沖區 42
已記憶集合總結 44
轉移和回收 47
終止 47
GC外部的并行活動 48
所有并行活動總結 48
所有串行活動的啟動 48
其他串行活動 49
年輕代調優 50
并發標記階段調優 52
混合垃圾收集階段回顧 54
混合垃圾收集階段調優 56
避免轉移失敗 59
引用處理 60
觀察引用處理 60
引用處理調優 62
引用 65
第4章 The Serviceability Agent 67
SA是什么 67
為什么要用SA 68
SA組件 68
JDK中的SA二進制文件 69
SA的JDK版本說明 69
SA如何獲得Hotspot虛擬機的內部數據結構 70
SA版本對照 71
SA調試工具 72
HSDB 72
HSDB工具 80
命令行Hotspot調試器CLHSDB 100
其他工具 103
CoreDump和崩潰Dump文件 109
調試非本地生成的Core文件 109
SA的共享庫問題 110
消除共享庫問題 110
SA的系統屬性 111
SA的環境變量 113
JDI實現 114
擴展SA工具 115
VisualVM的SA插件 118
VisualVM中怎樣安裝SA插件 119
SA插件使用 119
SA插件功能 120
用SA做故障分析 124
內存溢出錯誤分析 124
診斷語言層死鎖 132
事后分析Hotspot虛擬機崩潰 137
附錄 虛擬機命令行附加參數探秘 145
索引 155