Java是目前用戶最多、使用范圍最廣的軟件開發技術,Java的技術體系主要由支撐Java程序運行的虛擬機、提供各開發領域接口支持的Java類庫、Java編程語言及許許多多的第三方Java框架(如Spring、MyBatis等)構成。在國內,有關Java類庫API、Java語言語法及第三方框架的技術資料和書籍非常豐富,相比而言,有關Java虛擬機的資料卻顯得異常貧乏。
這種狀況很大程度上是由Java開發技術本身的一個重要優點導致的:在虛擬機層面隱藏了底層技術的復雜性以及機器與操作系統的差異性。運行程序的物理機千差萬別,而Java虛擬機則在千差萬別的物理機上面建立了統一的運行平臺,實現了在任意一臺Java虛擬機上編譯的程序,都能在任何其他Java虛擬機上正常運行。這一極大的優勢使得Java應用的開發比傳統C/C++應用的開發更高效快捷,程序員可以把主要精力放在具體業務邏輯,而不是放在保障物理硬件的兼容性上。通常情況下,一個程序員只要了解了必要的Java類庫API、Java語法,學習適當的第三方開發框架,就已經基本滿足日常開發的需要了。虛擬機會在用戶不知不覺中完成對硬件平臺的兼容及對內存等資源的管理工作。因此,了解虛擬機的運作并不是普通開發人員必備的,或者說首要學習的知識。
然而,凡事都具備兩面性。隨著Java技術的不斷發展,它已被應用于越來越多的領域之中。其中一些領域,如互聯網、能源、金融、通信等,對程序的性能、穩定性和擴展性方面會有極高的要求。一段程序很可能在10個人同時使用時完全正常,但是在10000個人同時使用時就會緩慢、死鎖甚至崩潰。毫無疑問,要滿足10000個人同時使用,需要更高性能的物理硬件,但是在絕大多數情況下,提升硬件性能無法等比例提升程序的運行性能和并發能力,甚至有可能對程序運行狀況沒有任何改善。這里面有Java虛擬機的原因:為了達到“所有硬件提供一致的虛擬平臺”的目的,犧牲了一些硬件相關的性能特性。更重要的是人為原因:如果開發人員不了解虛擬機諸多技術特性的運行原理,就無法寫出最適合虛擬機運行和自優化的代碼。
其實,目前商用的高性能Java虛擬機都提供了相當多的優化參數和調節手段,用于滿足應用程序在實際生產環境中對性能和穩定性的要求。如果只是為了入門學習,讓程序在自己的機器上正常工作,那么這些特性可以說是可有可無的;但是,如果用于生產開發,尤其是大規模的、企業級的生產開發,就迫切需要開發人員中至少有一部分人對虛擬機的特性及調節方法具有很清晰的認識。所以在Java開發體系中,對架構師、系統調優師、高級程序員等角色的需求一直都非常大。學習虛擬機中各種自動運作特性的原理也成為Java程序員成長路上最終必然會接觸到的一課。通過本書,讀者可以以一個相對輕松的方式學到虛擬機的運作原理。
本書面向的讀者
(1)使用Java技術體系的中、高級開發人員
Java虛擬機作為中、高級開發人員修煉的必要知識,有著較高的學習門檻,本書可作為學習虛擬機的教材。
(2)系統調優師
系統調優師是最近幾年才興起并迅速流行起來的職業,本書中的大量案例、代碼和調優實戰將會對系統調優師的日常工作有直接的參考作用。
(3)系統架構師
保障系統的性能、并發和伸縮等能力是系統架構師的主要職責之一,而這部分與虛擬機的運作密不可分,本書可以作為他們制定應用系統底層框架的參考資料。
如何閱讀本書
本書一共分為五個部分:走近Java、自動內存管理、虛擬機執行子系統、程序編譯與代碼優化、高效并發。各個部分之間基本上是互相獨立的,沒有必然的前后依賴關系,讀者可以從任何一個感興趣的專題開始閱讀,但是每個部分各個章節間則有先后順序。
這里并沒有假定所有讀者都在Java領域具備特別專業的技術水平,因此會在保證邏輯完整、描述準確的前提下,盡量用通俗的語言和案例去講述虛擬機中與開發關系最為密切的內容。但是,本書畢竟是在探討虛擬機的工作原理,不可避免地需要讀者有一定的技術基礎,而且本書的讀者定位是中、高級程序員群體,對于一些常用的開發框架、Java類庫API和Java語法等基礎知識點,將假設讀者已有所了解。
本書介紹的Java虛擬機并不局限于某一個特定發行商或者某一款特定虛擬機,只是由于OracleJDK/OpenJDK在市場占有率上的絕對優勢,其中的HotSpot虛擬機不可避免地成為本書主要分析、講解的對象,書中在涉及Java虛擬機自身實現相關的內容時,大多將以HotSpot虛擬機為目標對象來進行講解。但撰寫本書的意圖并不是去做HotSpot的源碼導讀或者解析,書中所講述的內容多為Java虛擬機的通用原理,即使讀者使用了HotSpot之外的其他Java虛擬機實現,也會有所收獲。
最后,非常希望讀者能跟隨本書的講解,把與實踐相關的內容親自驗證一遍,其中用到的代碼清單可以從華章圖書的網站(http://www.hzbook.com/)上下載。
語言約定
開始閱讀本書之前,在語言和技術上先與讀者建立如下約定:
·JDK從1.5版本開始,其官方的正式文檔與宣傳材料中的發行版本號啟用了JDK 5、6、7……的新命名方式;從2018年3月發布的JDK 10起,JDK的開發版本號(如java-version)也放棄了以前1.x的命名形式,改為按發布的日期時間命名。本書為了行文一致,所有場合統一采用發行版本號來指代所述的JDK版本。
·由于版面原因,本書中的許多示例代碼都沒有遵循最優的程序編寫風格,如使用的流沒有關閉流、直接使用System.out輸出日志等,請讀者在閱讀時注意這一點。
·本書講解中涉及JDK 7以前HotSpot虛擬機、JRockit虛擬機、WebLogic服務器等產品的所有者時,仍然會使用BEA和Sun公司的名稱,而不是Oracle。實際上BEA和Sun分別于2008年和2010年被Oracle公司收購,現在已經不存在這兩個商標了,但是它們毫無疑問都是在Java領域中做出過卓越貢獻的、值得程序員們紀念的先驅企業。
·本書第3版撰寫于2019年中期,此時JDK 13已有了技術預覽版(Early Access),但尚未正式發布。本書中所有的講解、討論都是基于這個時間點的Java技術的,但并不針對特定的JDK版本。如涉及JDK新版本中加入的功能,或在不同版本中有所變化的特性,筆者都會明確指出JDK的版本號,或專門闡述各個版本間的差異。
內容特色與更新
本書的第2版成文于2011至2012年間,出版于2013年,撰寫時是基于早期版本的JDK 7,彼時正值Oracle全面替代Sun公司領導Java技術發展的起點。經過將近十年的時間,今天JDK版本已經發展到了JDK 12及預覽版的JDK 13,整個Java技術體系一改Sun時代的遲緩作風,出現了許多激烈的變革,也涌現了不少令人欣喜的新變化、新風潮。我在撰寫本書第3版時,期望能把這些新的變化融合到已有的知識框架中,修改第2版中讀者反饋的問題,提升敘述的準確性與可讀性,這些期望中的更新使得本書字數從原有的24萬增加到35萬。因此,在前言部分,筆者針對每章列舉出主要更新的內容,以便閱讀過第2版的讀者可以快速定位,獲取到新的知識。當然,如果你尚有余暇,不妨從頭閱讀一次本書,相信會有與閱讀第2版時不一樣的體驗和收獲。
第一部分 走近Java
本書的第一部分為后文的研究和講解建立了良好的基礎。雖然了解Java技術的來龍去脈,以及編譯自己的OpenJDK對于讀者理解Java虛擬機并不是必須的,但是這些準備過程可以為走近Java技術和Java虛擬機提供良好的引導。第一部分只有第1章:
第1章 介紹了Java技術體系過去、現在的情況以及未來的發展趨勢,并在實踐中介紹了如何自己編譯一個OpenJDK 12。
[插圖]第3版更新:續寫了Java技術發展史,這幾年Java世界著實發生了很多值得記錄的大事件;完全重寫了第2版對未來Java的展望預測,當時暢想的Java新發展新變化全部如約而至,是時候把聚光燈交給下一個十年的Java了;OpenJDK開發、編譯也發生過不小的變動,本次更新將OpenJDK編譯的版本提升到12。
第二部分 自動內存管理
因為程序員把控制內存的權力交給了Java虛擬機,所以可以在編碼的時候享受自動內存管理的諸多優勢,不過也正因為這個原因,一旦出現內存泄漏和溢出方面的問題,如果不了解虛擬機是怎樣使用內存的,那排查錯誤將會成為一項異常艱難的工作。第二部分包括第2~5章:
第2章 介紹了虛擬機中內存是如何劃分的,哪部分區域、什么樣的代碼和操作可能導致內存溢出異常,并講解了各個區域出現內存溢出異常的常見原因。
[插圖]第3版更新:Java運行期數據區域是虛擬機的基礎結構,盡管JDK版本在快速發展,這塊內容仍然保持了相對的穩定,主要的變化是JDK 8時期的永久代的落幕和元空間的登場;除此以外,本章著重修正了第2版中對Java虛擬機棧描述的含糊與偏差之處,還更新了部分測試代碼,避免因JDK版本更迭導致與書中不一樣的結果。
第3章 介紹了垃圾收集的算法和HotSpot虛擬機中提供的幾款垃圾收集器的特點及運作原理。通過代碼實例驗證了Java虛擬機中自動內存分配及回收的主要規則。
[插圖]第3版更新:由于撰寫第2版時JDK 7剛剛發布,G1收集器尚無實踐數據可查,書中對此講述得比較含糊,本次更新完全重寫了這部分內容,并重點增加了JDK 11、12中新出現的ZGC和Shenandoah兩款低延遲全并發收集器的詳細原理解析,這是垃圾收集器未來的發展方向。對其他與收集器相關的更新,如統一收集器接口、Epsilon等也都做了對應介紹。此外,針對HotSpot中收集器實現的幾個關鍵技術點,如解決跨代引用的記憶集與卡表、解決并發標記的增量更新和原始快照算法,還有內存讀、寫屏障等技術都增加了專門的小節來進行介紹,以便幫讀者在后續深入閱讀HotSpot設計與源碼時打下良好的理論基礎。
第4章 介紹了隨JDK發布的基礎命令行工具與可視化的故障處理工具的使用方法。
[插圖]第3版更新:Java虛擬機的各種監控、管理等輔助工具的功能日益強大,幾乎每個版本在這些工具的數量、功能上都會或多或少有所變化,除了將第2版涉及的工具的變化依照JDK版本進行升級外,本章還新增了對JDK 9中加入的JHSDB的使用講解,并增加了對JFR和JMC的工作原理和使用方法的介紹,以及對部分JDK外部的工具(如JIT Watch)的簡要介紹。
第5章 分享了幾個比較有代表性的實際案例,還準備了一個所有開發人員都能“親身實戰”的練習,希望讀者能通過實踐來獲得故障處理和調優的經驗。
[插圖]第3版更新:對案例部分進行了更新和增補,著重補充了與前3章新增內容相對應的問題處理案例。不過對實戰部分,軟件版本的落后并未影響筆者要表達的內容,原有的實戰目前仍具有相同的實戰價值,在第3版里筆者也并未刻意將Eclipse和HotSpot升級后重寫一次。
第三部分 虛擬機執行子系統
執行子系統是虛擬機中必不可少的組成部分,了解了虛擬機如何執行程序,才能更好地理解怎樣才能寫出優秀的代碼。第三部分包括第6~9章:
第6章 講解了Class文件結構中的各個組成部分,以及每個部分的定義、數據結構和使用方法,以實戰的方式演示了Class的數據是如何存儲和訪問的。
[插圖]第3版更新:筆者認為本章內容更適合以“技術手冊”的形式存在,即適合查閱多于適合閱讀,但因為Class文件格式是虛擬機的基礎知識,所以盡管枯燥卻無法回避。本次更新將Class文件格式的版本跟進到了JDK 12,《Java虛擬機規范》對Class文件格式進行的增強也會在本章中反映,內容相對瑣碎。例如,為了實現JDK 9的Java模塊化系統,屬性表中新增了Module、ModulePackages、ModuleMain-Class三項新屬性,常量池中加入了CONSTANT_Module_info和CONSTANT_Package_info兩個常量。為了實現JDK 11新增的嵌套內(Java中的內部類)訪問控制的API,屬性表中又增加了NestHost和NestMembers兩項屬性。為進一步加強動態語言支持,CONSTANT_Dynamic_info常量也在JDK 11期間加入常量池……
第7章 介紹了類加載過程的“加載”“驗證”“準備”“解析”和“初始化”五個階段中虛擬機分別進行了哪些動作,還介紹了類加載器的工作原理及其對虛擬機的意義。
[插圖]第3版更新:隨著Class文件格式的發展,類加載的各個過程都發生了一些細節性變動,本章將會按照JDK 12版本的《Java虛擬機規范》的標準來同步更新這些內容。此外,在JDK 9時引入了Java模塊化系統,這是近年來Java技術的一次重要升級,也是對類加載部分影響巨大的一項變革,在本章將加入專門的小節對其進行講述。
第8章 分析了虛擬機在執行代碼時,如何找到正確的方法、如何執行方法內的字節碼,以及執行代碼時涉及的內存結構。
[插圖]第3版更新:本章講述的是Java虛擬機執行子系統的概念模型,這部分屬于相對穩定的內容,變化不大,本次主要更新了Java虛擬機對動態類型語言支持的增強。
第9章 通過幾個類加載及執行子系統的案例,介紹了使用類加載器和處理字節碼的一些值得欣賞和借鑒的思路,并通過一個實戰練習加深讀者對前面理論知識的理解。
[插圖]第3版更新:原有章節所涉及的案例中,程序、類庫、工具的版本已經較為陳舊,本次更新對這些案例涉及的版本進行了升級,以反映在模塊化、Lambda表達式、動態語言等新技術出現后它們的相應變化。
第四部分 程序編譯與代碼優化
Java程序從源碼編譯成字節碼,再從字節碼編譯成本地機器碼的這兩個過程,從整體來看其實等同于一個傳統編譯器所執行的編譯前端、后端過程。第四部分包括第10~11章:
第10章 分析了Java語言中泛型、主動裝箱拆箱、條件編譯等多種語法糖的前因后果,并實戰練習了如何使用插入式注解處理器來完成一個檢查程序命名規范的編譯器插件。
[插圖]第3版更新:對第2版介紹泛型的小節進行了全文重寫,描述了不同語言里泛型實現的方式、Java泛型出現的歷史背景和使用類型擦除來實現泛型所帶來的一些限制,并介紹了未來可能會在Java中出現的值類型等內容。
第11章 講解了虛擬機的熱點探測方法、HotSpot的即時編譯器、編譯觸發條件,以及如何從虛擬機外部觀察和分析即時編譯的數據和結果,還選擇了幾種常見的編譯期優化技術進行講解。
[插圖]第3版更新:專門增加了介紹提前編譯器的章節;由于HotSpot中新的Graal編譯器的加入,書中除了同步增加Graal編譯器、JVMCI接口等內容,為了使讀者可以在HotSpot編譯器上進行實戰練習,在本書第3版中還新增了許多編譯器的實戰內容。
第五部分 高效并發
Java語言和虛擬機提供了原生的、完善的多線程支持,使得它天生就適合開發多線程并發的應用程序。不過我們不能期望系統來完成所有與并發相關的處理,了解并發的內幕也是成為一位高級程序員不可缺少的課程。第五部分包括第12~13章:
第12章 講解了虛擬機Java內存模型的結構及操作,以及原子性、可見性和有序性在Java內存模型中的體現;介紹了先行發生原則的規則及使用,以及線程在Java語言之中是如何實現的;還提前介紹了目前仍然在實驗室狀態的Java協程的相關內容。
第3版更新:重寫了原有的對Java內存模型部分過時和過于晦澀的描述,增加了面向Java未來基于協程的新并發模型的介紹。
第13章 介紹了線程安全所涉及的概念和分類、同步實現的方式及虛擬機的底層運作原理,并且介紹了虛擬機實現高效并發所做的一系列鎖優化措施。
[插圖]第3版更新:本章主體內容并沒有過多變化,但對不少細節進行了修飾,對一些讀者疑問較多的地方進行了補充講解。
* [ ] 參考資料
本書名為“深入理解Java虛擬機”,但要想真的深入理解虛擬機,僅憑一本書肯定是遠遠不夠的,讀者可以通過以下方式查找到更多關于Java虛擬機方面的資料。筆者在寫作此書的時候,也從下面這些參考資料中得到過很大的幫助。
* [ ] 1、書籍
* 《Java虛擬機規范》
要學習虛擬機,《Java虛擬機規范》無論如何都是必須讀的。這本書的概念和細節描述與Sun的早期虛擬機(Sun Classic虛擬機)高度吻合,隨著技術的發展,高性能虛擬機真正的細節實現方式已經漸漸與虛擬機規范所描述的方式差距越來越大,如果只能選擇一本參考書來了解Java虛擬機,那必然是這本書。
* 《Java語言規范》
雖然Java虛擬機并不是Java語言專有的,但是了解Java語言的各種細節規定對虛擬機的行為也是很有幫助的,它與《Java虛擬機規范》一樣都是Oracle官方直接出版的書籍,而且這本書還是由Java之父James Gosling親自執筆撰寫。
* 《垃圾回收算法手冊:自動內存管理的藝術》
2016年3月由機械工業出版社引進翻譯,這是一本真正的教科書式的學術著作,是垃圾收集技術領域中的唯一必讀的書籍。該書從硬件與軟件的發展給垃圾回收所帶來的新挑戰出發,探討了這些挑戰給高性能垃圾回收器的設計者與實現者所帶來的影響,涵蓋了并行垃圾回收、增量式垃圾回收、并發垃圾回收以及實時垃圾回收,描述各種算法與概念。唯一缺點是由于過于專業,所以顯得比較晦澀,不適合作為入門書籍使用。
* 《Virtual Machines:Versatile Platforms for Systems and Processes》
這是一本虛擬化技術的百科全書,幫助讀者理解“虛擬機”一詞到底指代什么,有什么不同類型,大概有哪些實現方法等。此書并不直接針對Java虛擬機,出版于2005年,而且國內并沒有中文版,但即使有這些因素限制,仍然推薦讀者閱讀此書以建立對虛擬機的全局性觀念。
* 《Java性能優化權威指南》
此書是“The Java”系列(該系列中最出名的《Effective Java》許多人都讀過)圖書中最新的一本,但也有一定的歷史了。2011年10月出版,2014年3月由人民郵電出版社引進翻譯。這本書并非全部都圍繞Java虛擬機展開(只有第3、4、7章直接與Java虛擬機相關),而是從操作系統到基于Java的上層程序性能度量和調優進行全面介紹。其中涉及Java虛擬機的內容具備一定深度和很好的可實踐性。
* [ ] 2、網站資源
* 高級語言虛擬機圈子:http://hllvm.group.iteye.com/。
里面有一些關于虛擬機的討論,并不只限于Java虛擬機,包括了所有針對高級語言虛擬機(High-Level Language Virtual Machine)的討論,不過該網站針對Java虛擬機的討論還是絕對的主流。圈主RednaxelaFX(莫樞)的博客(http://rednaxelafx.iteye.com/) 是另外一個非常有價值的虛擬機及編譯原理等資料的分享園地。
* HotSpot Internals:https://wiki.openjdk.java.net/display/HotSpot/Main。
這是一個關于OpenJDK的Wiki網站,許多文章都由JDK的開發團隊編寫,更新很慢,但是有很大的參考價值。
* The HotSpot Group:http://openjdk.java.net/groups/hotspot/。
HotSpot組群,里面有關于虛擬機開發、編譯器、垃圾收集和運行時四個郵件組,包含了關于HotSpot虛擬機最新的討論。
* [ ] 聯系作者
在本書交稿的時候,我并沒有想象中那樣興奮或放松,寫作之時那種“戰戰兢兢、如履薄冰”的感覺依然縈繞在心頭。在每一章、每一節落筆之時,我都在考慮如何才能把各個知識點更有條理地講述出來,都在擔心會不會由于自己理解有偏差而誤導了大家。囿于我的寫作水平和寫作時間,書中難免存在不妥之處,所以大家如有任何意見或建議,歡迎到本工程地址https://github.com/fenixsoft/jvm_book 與我聯系。相信寫書與寫程序一樣,作品一定都是不完美的,因為不完美,我們才有不斷追求完美的動力。
- 聲明
- 前言
- 致謝
- 第一部分 走近Java
- 第1章 走近Java
- 1.1 概述
- 1.2 Java技術體系
- 1.3 Java發展史
- 1.4 Java虛擬機家族
- 1.4.1 虛擬機始祖:Sun Classic/Exact VM
- 1.4.2 武林盟主:HotSpot VM
- 1.4.3 小家碧玉:Mobile/Embedded VM
- 1.4.4 天下第二:BEA JRockit/IBM J9 VM
- 1.4.5 軟硬合璧:BEA Liquid VM/Azul VM
- 1.4.6 挑戰者:Apache Harmony/Google Android Dalvik VM
- 1.4.7 沒有成功,但并非失敗:Microsoft JVM及其他
- 1.4.8 百家爭鳴
- 1.5 展望Java技術的未來
- 1.5.1 無語言傾向
- 1.5.2 新一代即時編譯器
- 1.5.3 向Native邁進
- 1.5.4 靈活的胖子
- 1.5.5 語言語法持續增強
- 1.6 實戰:自己編譯JDK
- 1.6.1 獲取源碼
- 1.6.2 系統需求
- 1.6.3 構建編譯環境
- 1.6.4 進行編譯
- 1.6.5 在IDE工具中進行源碼調試
- 1.7 本章小結
- 第二部分 自動內存管理
- 第2章 Java內存區域與內存溢出異常
- 2.1 概述
- 2.2 運行時數據區域
- 2.2.1 程序計數器
- 2.2.2 Java虛擬機棧
- 2.2.3 本地方法棧
- 2.2.4 Java堆
- 2.2.5 方法區
- 2.2.6 運行時常量池
- 2.2.7 直接內存
- 2.3 HotSpot虛擬機對象探秘
- 2.3.1 對象的創建
- 2.3.2 對象的內存布局
- 2.3.3 對象的訪問定位
- 2.4 實戰:OutOfMemoryError異常
- 2.4.1 Java堆溢出
- 2.4.2 虛擬機棧和本地方法棧溢出
- 2.4.3 方法區和運行時常量池溢出
- 2.4.4 本機直接內存溢出
- 2.5 本章小結
- 第3章 垃圾收集器與內存分配策略
- 3.1 概述
- 3.2 對象已死?
- 3.2.1 引用計數算法
- 3.2.2 可達性分析算法
- 3.2.3 再談引用
- 3.2.4 生存還是死亡?
- 3.2.5 回收方法區
- 3.3 垃圾收集算法
- 3.3.1 分代收集理論
- 3.3.2 標記-清除算法
- 3.3.3 標記-復制算法
- 3.3.4 標記-整理算法
- 3.4 HotSpot的算法細節實現
- 3.4.1 根節點枚舉
- 3.4.2 安全點
- 3.4.3 安全區域
- 3.4.4 記憶集與卡表
- 3.4.5 寫屏障
- 3.4.6 并發的可達性分析
- 3.5 經典垃圾收集器
- 3.5.1 Serial收集器
- 3.5.2 ParNew收集器
- 3.5.3 Parallel Scavenge收集器
- 3.5.4 Serial Old收集器
- 3.5.5 Parallel Old收集器
- 3.5.6 CMS收集器
- 3.5.7 Garbage First收集器
- 3.6 低延遲垃圾收集器
- 3.6.1 Shenandoah收集器
- 3.6.2 ZGC收集器
- 3.7 選擇合適的垃圾收集器
- 3.7.1 Epsilon收集器
- 3.7.2 收集器的權衡
- 3.7.3 虛擬機及垃圾收集器日志
- 3.7.4 垃圾收集器參數總結
- 3.8 實戰:內存分配與回收策略
- 3.8.1 對象優先在Eden分配
- 3.8.2 大對象直接進入老年代
- 3.8.3 長期存活的對象將進入老年代
- 3.8.4 動態對象年齡判定
- 3.8.5 空間分配擔保
- 3.9 本章小結
- 第4章 虛擬機性能監控、故障處理工具
- 4.1 概述
- 4.2 基礎故障處理工具
- 4.2.1 jps:虛擬機進程狀況工具
- 4.2.2 jstat:虛擬機統計信息監視工具
- 4.2.3 jinfo:Java配置信息工具
- 4.2.4 jmap:Java內存映像工具
- 4.2.5 jhat:虛擬機堆轉儲快照分析工具
- 4.2.6 jstack:Java堆棧跟蹤工具
- 4.2.7 基礎工具總結
- 4.3 可視化故障處理工具
- 4.3.1 JHSDB:基于服務性代理的調試工具
- 4.3.2 JConsole:Java監視與管理控制臺
- 4.3.3 VisualVM:多合-故障處理工具
- 4.3.4 Java Mission Control:可持續在線的監控工具
- 4.4 HotSpot虛擬機插件及工具
- 4.5 本章小結
- 第5章 調優案例分析與實戰
- 5.1 概述
- 5.2 案例分析
- 5.2.1 大內存硬件上的程序部署策略
- 5.2.2 集群間同步導致的內存溢出
- 5.2.3 堆外內存導致的溢出錯誤
- 5.2.4 外部命令導致系統緩慢
- 5.2.5 服務器虛擬機進程崩潰
- 5.2.6 不恰當數據結構導致內存占用過大
- 5.2.7 由Windows虛擬內存導致的長時間停頓
- 5.2.8 由安全點導致長時間停頓
- 5.3 實戰:Eclipse運行速度調優
- 5.3.1 調優前的程序運行狀態
- 5.3.2 升級JDK版本的性能變化及兼容問題
- 5.3.3 編譯時間和類加載時間的優化
- 5.3.4 調整內存設置控制垃圾收集頻率
- 5.3.5 選擇收集器降低延遲
- 5.4 本章小結
- 第三部分 虛擬機執行子系統
- 第6章 類文件結構
- 6.1 概述
- 6.2 無關性的基石
- 6.3 Class類文件的結構
- 6.3.1 魔數與Class文件的版本
- 6.3.2 常量池
- 6.3.3 訪問標志
- 6.3.4 類索引、父類索引與接口索引集合
- 6.3.5 字段表集合
- 6.3.6 方法表集合
- 6.3.7 屬性表集合
- 6.4 字節碼指令簡介
- 6.4.1 字節碼與數據類型
- 6.4.2 加載和存儲指令
- 6.4.3 運算指令
- 6.4.4 類型轉換指令
- 6.4.5 對象創建與訪問指令
- 6.4.6 操作數棧管理指令
- 6.4.7 控制轉移指令
- 6.4.8 方法調用和返回指令
- 6.4.9 異常處理指令
- 6.4.10 同步指令
- 6.5 公有設計,私有實現
- 6.6 Class文件結構的發展
- 6.7 本章小結
- 第7章 虛擬機類加載機制
- 7.1 概述
- 7.2 類加載的時機
- 7.3 類加載的過程
- 7.3.1 加載
- 7.3.2 驗證
- 7.3.3 準備
- 7.3.4 解析
- 7.3.5 初始化
- 7.4 類加載器
- 7.4.1 類與類加載器
- 7.4.2 雙親委派模型
- 7.4.3 破壞雙親委派模型
- 7.5 Java模塊化系統
- 7.5.1 模塊的兼容性
- 7.5.2 模塊化下的類加載器
- 7.6 本章小結
- 第8章 虛擬機字節碼執行引擎
- 8.1 概述
- 8.2 運行時棧幀結構
- 8.2.1 局部變量表
- 8.2.2 操作數棧
- 8.2.3 動態連接
- 8.2.4 方法返回地址
- 8.2.5 附加信息
- 8.3 方法調用
- 8.3.1 解析
- 8.3.2 分派
- 8.4 動態類型語言支持
- 8.4.1 動態類型語言
- 8.4.2 Java與動態類型
- 8.4.3 java.lang.invoke包
- 8.4.4 invokedynamic指令
- 8.4.5 實戰:掌控方法分派規則
- 8.5 基于棧的字節碼解釋執行引擎
- 8.5.1 解釋執行
- 8.5.2 基于棧的指令集與基于寄存器的指令集
- 8.5.3 基于棧的解釋器執行過程
- 8.6 本章小結
- 第9章 類加載及執行子系統的案例與實戰
- 9.1 概述
- 9.2 案例分析
- 9.2.1 Tomcat:正統的類加載器架構
- 9.2.2 OSGi:靈活的類加載器架構
- 9.2.3 字節碼生成技術與動態代理的實現
- 9.2.4 Backport工具:Java的時光機器
- 9.3 實戰:自己動手實現遠程執行功能
- 9.3.1 目標
- 9.3.2 思路
- 9.3.3 實現
- 9.3.4 驗證
- 9.4 本章小結
- 第四部分 程序編譯與代碼優化
- 第10章 前端編譯與優化
- 10.1 概述
- 10.2 Javac編譯器
- 10.2.1 Javac的源碼與調試
- 10.2.2 解析與填充符號表
- 10.2.3 注解處理器
- 10.2.4 語義分析與字節碼生成
- 10.3 Java語法糖的味道
- 10.3.1 泛型
- 10.3.2 自動裝箱、拆箱與遍歷循環
- 10.3.3 條件編譯
- 10.4 實戰:插入式注解處理器
- 10.4.1 實戰目標
- 10.4.2 代碼實現
- 10.4.3 運行與測試
- 10.4.4 其他應用案例
- 10.5 本章小結
- 第11章 后端編譯與優化
- 11.1 概述
- 11.2 即時編譯器
- 11.2.1 解釋器與編譯器
- 11.2.2 編譯對象與觸發條件
- 11.2.3 編譯過程
- 11.2.4 實戰:查看及分析即時編譯結果
- 11.3 提前編譯器
- 11.3.1 提前編譯的優劣得失
- 11.3.2 實戰:Jaotc的提前編譯
- 11.4 編譯器優化技術
- 11.4.1 優化技術概覽
- 11.4.2 方法內聯
- 11.4.3 逃逸分析
- 11.4.4 公共子表達式消除
- 11.4.5 數組邊界檢查消除
- 11.5 實戰:深入理解Graal編譯器
- 11.5.1 歷史背景
- 11.5.2 構建編譯調試環境
- 11.5.3 JVMCI編譯器接口
- 11.5.4 代碼中間表示
- 11.5.5 代碼優化與生成
- 11.6 本章小結
- 第五部分 高效并發
- 第12章 Java內存模型與線程
- 12.1 概述
- 12.2 硬件的效率與一致性
- 12.3 Java內存模型
- 12.3.1 主內存與工作內存
- 12.3.2 內存間交互操作
- 12.3.3 對于volatile型變量的特殊規則
- 12.3.4 針對long和double型變量的特殊規則
- 12.3.5 原子性、可見性與有序性
- 12.3.6 先行發生原則
- 12.4 Java與線程
- 12.4.1 線程的實現
- 12.4.2 Java線程調度
- 12.4.3 狀態轉換
- 12.5 Java與協程
- 12.5.1 內核線程的局限
- 12.5.2 協程的復蘇
- 12.5.3 Java的解決方案
- 12.6 本章小結
- 第13章 線程安全與鎖優化
- 13.1 概述
- 13.2 線程安全
- 13.2.1 Java語言中的線程安全
- 13.2.2 線程安全的實現方法
- 13.3 鎖優化
- 13.3.1 自旋鎖與自適應自旋
- 13.3.2 鎖消除
- 13.3.3 鎖粗化
- 13.3.4 輕量級鎖
- 13.3.5 偏向鎖
- 13.4 本章小結
- 附錄A 在Windows系統下編譯OpenJDK 6
- 附錄B 展望Java技術的未來(2013年版)
- 附錄C 虛擬機字節碼指令表
- 附錄D 對象查詢語言(OQL)簡介
- 附錄E JDK歷史版本軌跡