深入理解Java虛擬機:JVM高級特性與最佳實踐

深入理解Java虛擬機:JVM高級特性與最佳實踐

《深入理解Java虛擬機JVM高級特性與最佳實踐》是2011年機械工業出版社出版的圖書,作者是周志明。

基本介紹

  • 書名:深入理解Java虛擬機:JVM高級特性與最佳實踐
  • 作者:周志明
  • ISBN:9787111349662
  • 出版社:機械工業出版社
  • 出版時間:2011年6月
  • 裝幀:平裝
  • 開本:16開
  • 頁碼:387
內容簡介,媒體評論,作譯者簡介,前言,本書讀者對象,如何閱讀本書,內容特色,目錄,

內容簡介

作為一位java程式設計師,你是否也曾經想深入理解java虛擬機,但是卻被它的複雜和深奧拒之門外?沒關係,《深入理解java虛擬機:jvm高級特性與最佳實踐》極盡化繁為簡之妙,能帶領你在輕鬆中領略java虛擬機的奧秘。《深入理解java虛擬機:jvm高級特性與最佳實踐》是近年來國內出版的唯一一本與java虛擬機相關的專著,也是唯一一本同時從核心理論和實際運用這兩個角度去探討java虛擬機的著作,不僅理論分析得透徹,而且書中包含的典型案例和最佳實踐也極具現實指導意義。
全書共分為五大部分。第一部分從巨觀的角度介紹了整個java技術體系的過去、現在和未來,以及如何獨立地編譯一個openjdk7,這對理解後面的內容很有幫助。第二部分講解了jvm的自動記憶體管理,包括虛擬機記憶體區域的劃分原理以及各種記憶體溢出異常產生的原因;常見的垃圾收集算法以及垃圾收集器的特點和工作原理;常見的虛擬機的監控與調試工具的原理和使用方法。第三部分分析了虛擬機的執行子系統,包括class的檔案結構以及如何存儲和訪問class中的數據;虛擬機的類創建機制以及類載入器的工作原理和它對虛擬機的意義;虛擬機位元組碼的執行引擎以及它在實行代碼時涉及的記憶體結構。第四部分講解了程式的編譯與代碼的最佳化,闡述了泛型、自動裝箱拆箱、條件編譯等語法糖的原理;講解了虛擬機的熱點探測方法、hotspot的即時編譯器、編譯觸發條件,以及如何從虛擬機外部觀察和分析jit編譯的數據和結果。第五部分探討了java實現高效並發的原理,包括jvm記憶體模型的結構和操作;原子性、可見性和有序性在java記憶體模型中的體現;先行發生原則的規則和使用;執行緒在java語言中的實現原理;虛擬機實現高效並發所做的一系列鎖最佳化措施。
《深入理解java虛擬機:jvm高級特性與最佳實踐》適合所有java程式設計師、系統調優師和系統架構師閱讀。

媒體評論

Java 程式是如何運行的?Java虛擬機在其中扮演了怎樣的角色?如何讓Java程式具有更高的並發性?許多Java程式設計師都會諸如此類的疑問。無奈,國內在很長一段時間裡都沒有一本從實際套用的角度講解Java虛擬機的著作,《深入理解Java虛擬機:JVM高級特性與最佳實踐》的出版可謂填補了這個空白。它從Java程式設計師的角度出發,系統地將Java程式運行過程中涉及的各種知識整合到了一起,並配以日常工作中可能會碰到的疑難案例,引領讀者輕鬆踏上探索Java虛擬機的旅途,是廣大對Java虛擬機感興趣的讀者的福音!——莫樞(RednaxelaFX) 虛擬機和程式語言愛好者
在武俠的世界裡,無論是至剛至強的《易筋經》,還是陰柔無比的《葵花寶典》,都離不開內功修煉。沒有了內功心法,這些武術只是花拳繡腿的拙劣表演而已。軟體業是武林江湖的一個翻版,也有著大量的模式、套路、規範等外功,但“外功修行,內功修神”,要想成為“掃地僧”一樣的絕世高人,此書是必備的。——秦小波 資深Java技術專家/著有暢銷書《設計模式之禪》
對Java程式設計師來說,Java虛擬機可以說是既熟悉又神秘,很少Java程式設計師能夠抑制自己探究它的衝動。可惜,分析JVM實現原理的書籍(特別是國內作者出版的)是少之又少。《深入理解Java虛擬機:JVM高級特性與最佳實踐》的出版可謂Java程式設計師的福音,作者將自己多年來在Java虛擬機領域的實踐經驗和研究心得呈現在了這《深入理解Java虛擬機:JVM高級特性與最佳實踐》中,不僅系統地講解了Java虛擬機工作機制和底層原理,而且更難能可貴的是與實踐很好地結合了起來,具有非常強的實踐指導意義,強烈推薦!——計文柯 資深Java技術專家/著有暢銷書《Spring技術內幕:深入解析Spring架構設計與實現原理》

作譯者簡介

周志明,資深Java技術專家,對JavaEE企業級套用開發、OSGi、Java虛擬機和工作流等都有深入的研究,並在大量的實踐中積累了豐富的經驗。尤其精通Java虛擬機,撰寫了大量與JVM相關的經典文章,被各大技術社區爭相轉載,是ITeye等技術社區公認的Java虛擬機方面的領袖人物之一。現任遠光軟體股份有限公司平台開發部經理兼平台架構師,先後參加與過國家電網、南方電網等多個國家級大型ERP項目的平台架構工作,對軟體系統架構也有深刻的認識和體會。

前言

Java是目前用戶最多、使用範圍最廣的軟體開發技術,Java的技術體系主要由支撐Java程式運行的虛擬機、為各開發領域提供接口支持的Java API、Java程式語言及許許多多的第三方Java框架(如Spring和Struts等)構成。在國內,有關Java API、Java語言及第三方框架的技術資料和書籍非常豐富,相比之下,有關Java虛擬機的資料卻顯得異常貧乏。
這種狀況很大程度上是由Java開發技術本身的一個重要優點導致的:在虛擬機層面隱藏了底層技術的複雜性以及機器與作業系統的差異性。運行程式的物理機器情況千差萬別,而Java虛擬機則在千差萬別的物理機上面建立了統一的運行平台,實現了在任意一台虛擬機上編譯的程式都能在任何一台虛擬機上正常運行。這一極大的優勢使得Java套用的開發比傳統C/C++套用的開發更高效和快捷,程式設計師可以把主要精力集中在具體業務邏輯上,而不是物理硬體的兼容性上。一般情況下,一個程式設計師只要了解了必要的Java API、Java語法並學習適當的第三方開發框架,就已經基本能滿足日常開發的需要了,虛擬機會在用戶不知不覺中完成對硬體平台的兼容以及對記憶體等資源的管理工作。因此,了解虛擬機的運作並不是一般開發人員必須掌握的知識。
然而,凡事都具備兩面性。隨著Java技術的不斷發展,它被套用于越來越多的領域之中。其中一些領域,如電力、金融、通信等,對程式的性能、穩定性和可擴展性方面都有極高的要求。一個程式很可能在10個人同時使用時完全正常,但是在10000個人同時使用時就會變慢、死鎖甚至崩潰。毫無疑問,要滿足10000個人同時使用需要更高性能的物理硬體,但是在絕大多數情況下,提升硬體效能無法等比例地提升程式的性能和並發能力,有時甚至可能對程式的性能沒有任何改善作用。這裡面有Java虛擬機的原因:為了達到為所有硬體提供一致的虛擬平台的目的,犧牲了一些硬體相關的性能特性。更重要的是人為原因:開發人員如果不了解虛擬機的一些技術特性的運行原理,就無法寫出最適合虛擬機運行和可自最佳化的代碼。
其實,目前商用的高性能Java虛擬機都提供了相當多的最佳化特性和調節手段,用於滿足應用程式在實際生產環境中對性能和穩定性的要求。如果只是為了入門學習,讓程式在自己的機器上正常運行,那么這些特性可以說是可有可無的;如果用於生產環境,尤其是企業級套用開發中,就迫切需要開發人員中至少有一部分人對虛擬機的特性及調節方法具有很清晰的認識,所以在Java開發體系中,對架構師、系統調優師、高級程式設計師等角色的需求一直都非常大。學習虛擬機中各種自動運作的特性的原理也成為了Java程式設計師成長道路上必然會接觸到的一課。通過本書,讀者可以以一種相對輕鬆的方式學習虛擬機的運作原理,對Java程式設計師的成長也有較大的幫助。

本書讀者對象

(1) 使用Java技術體系的中、高級開發人員
Java虛擬機作為中、高級開發人員必須修煉的知識,有著較高的學習門檻,本書可作為學習虛擬機的優秀教材。
(2) 系統調優師
系統調優師是近幾年才興起的職業,本書中的大量案例、代碼和調優實戰將會對系統調優師的日常工作有直接的幫助。
(3) 系統架構師
保障系統高效、穩定和可伸縮是系統架構師的主要職責之一,而這與虛擬機的運作密不可分,本書可以作為他們設計套用系統底層框架的參考資料。

如何閱讀本書

本書一共分為五個部分:走近Java、自動記憶體管理機制、虛擬機執行子系統、程式編譯與代碼最佳化、高效並發。各個部分基本上是相互獨立的,沒有必然的前後依賴關係,讀者可以從任何一個感興趣的專題開始閱讀,但是每個部分中的各個章節間有先後順序。
本書並不假設讀者在Java領域具備很專業的技術水平,因此在保證邏輯準確的前提下,儘量用通俗的語言和案例講述虛擬機中與開發關係最為密切的內容。當然學習虛擬機技術本身就需要讀者有一定的技術基礎,且本書的讀者定位是中、高級程式設計師,因此本書假設讀者自己了解一些常用的開發框架、Java API和Java語法等基礎知識。
語言約定
本書在語言和技術上有如下的約定:
本書中提到HotSpot虛擬機、JRockit虛擬機、WebLogic伺服器等產品的所有者時,仍然使用Sun和BEA公司的名稱。實際上BEA和Sun分別於2008年和2010年被Oracle公司收購,現在已經不存在這兩個商標了,但是毫無疑問它們都是對Java領域做出過卓越貢獻的、值得程式設計師紀念的公司。
JDK從1.5版本開始,在官方的正式文檔與宣傳資料中已經不再使用類似“JDK 1.5”的名稱,只有在程式設計師內部使用的開發版本號 (Developer Version,例如java -version的輸出)中才繼續沿用1.5、1.6和1.7的版本號,而公開版本號(Product Version)則改為JDK 5、JDK 6和JDK 7的命名方式。為了行文一致,本書所有場合統一採用開發版本號的命名方式。
由於版面關係,本書中的許多示例代碼都沒有遵循最優的代碼編寫風格,如使用的流沒有關閉流等,請讀者在閱讀時注意這一點。
如果沒有特殊說明,本書中所有的討論都是以Sun JDK 1.6為技術平台的。不過如果有某個特性在各個版本間的變化較大,一般都會說明它在各個版本間的差異。

內容特色

第一部分 走近Java
本書的第一部分為後文的講解建立了良好的基礎。儘管了解Java技術的來龍去脈,以及編譯自己的OpenJDK對於讀者理解Java虛擬機並不是必需的,但是這些準備過程可以為走近Java技術和Java虛擬機提供很好的引導。第一部分只有第1章:
第1章 介紹了Java技術體系的過去、現在和未來的發展趨勢,並介紹了如何獨立編譯一個OpenJDK 7。
第二部分 自動記憶體管理機制
因為程式設計師把記憶體控制的權力交給了Java虛擬機,所以可以在編碼的時候享受自動記憶體管理的諸多優勢,不過也正因為這個原因,一旦出現記憶體泄漏和溢出方面的問題,如果不了解虛擬機是怎樣使用記憶體的,那么排查錯誤將會成為一項異常艱難的工作。第二部分包括第2~5章:
第2章 講解了虛擬機中的記憶體是如何劃分的,哪部分區域、什麼樣的代碼和操作可能導致記憶體溢出異常,並講解了各個區域出現記憶體溢出異常的常見原因。
第3章 分析了垃圾收集的算法和JDK 1.6中提供的幾款垃圾收集器的特點及運作原理,通過代碼實例驗證了Java虛擬機中的自動記憶體分配及回收的主要規則。
第4章 介紹了隨JDK發布的6個命令行工具與2個可視化的故障處理工具的使用方法。
第5章 與讀者分享了幾個比較有代表性的實際案例,還準備了一個所有開發人員都能“親身實戰”的練習,讀者可通過實踐來獲得故障處理和調優的經驗。
第三部分 虛擬機執行子系統
執行子系統是虛擬機中必不可少的組成部分,了解了虛擬機如何執行程式,才能寫出更優秀的代碼。第三部分包括第6~9章:
第6章 講解了Class檔案結構中的各個組成部分,以及每個部分的定義、數據結構和使用方法,以實戰的方式演示了Class的數據是如何存儲和訪問的。
第7章 介紹了在類載入過程的“載入”、“驗證”、“準備”、“解析”和“初始化”這五個階段中虛擬機分別執行了哪些動作,還介紹了類載入器的工作原理及其對虛擬機的意義。
第8章 分析了虛擬機在執行代碼時如何找到正確的方法,如何執行方法內的位元組碼,以及執行代碼時涉及的記憶體結構。
第9章 通過四個類載入及執行子系統的案例,分享了使用類載入器和處理位元組碼的一些值得欣賞和借鑑的思路,並通過一個實戰練習來加深對前面理論知識的理解。
第四部分 程式編譯與代碼最佳化
Java程式從源碼編譯成位元組碼和從位元組碼編譯成本地機器碼的這兩個過程,合併起來其實就等同於一個傳統編譯器所執行的編譯過程。第四部分包括第10和11章:
第10章 分析了Java語言中的泛型、自動裝箱拆箱、條件編譯等多種語法糖的前因後果,並通過實戰案例演示了如何使用插入式註解處理器來實現一個檢查程式命名規範的編譯器外掛程式。
第11章 講解了虛擬機的熱點探測方法、HotSpot的即時編譯器、編譯觸發條件,以及如何從虛擬機外部觀察和分析JIT編譯的數據和結果。此外,還講解了幾種常見的編譯期最佳化技術。
第五部分 高效並發
Java語言和虛擬機提供了原生的、完善的多執行緒支持,使得它天生就適合開發多執行緒並發的應用程式。不過我們不能期望系統來完成所有與並發相關的處理,了解並發的內幕也是一個高級程式設計師不可缺少的課程。第五部分包括第12和13章:
第12章 講解了虛擬機的Java記憶體模型的結構和操作,以及原子性、可見性和有序性在Java記憶體模型中的體現,介紹了先行發生原則及使用,還講解了執行緒在Java語言中是如何實現的。
第13章 介紹了執行緒安全所涉及的概念和分類、同步實現的方式以及虛擬機的底層運作原理,並且還介紹了虛擬機實現高效並發所採取的一系列鎖最佳化措施。

目錄

前 言
致 謝
第一部分 走近Java
第1章 走近Java / 2
1.1 概述 / 2
1.2 Java技術體系 / 3
1.3 Java發展史 / 5
1.4 展望Java技術的未來 / 9
1.4.1 模組化 / 9
1.4.2 混合語言 / 9
1.4.3 多核並行 / 11
1.4.4 進一步豐富語法 / 12
1.4.5 64位虛擬機 / 13
1.5 實戰:自己編譯JDK / 13
1.5.1 獲取JDK源碼 / 13
1.5.2 系統需求 / 14
1.5.3 構建編譯環境 / 15
1.5.4 準備依賴項 / 17
1.5.5 進行編譯 / 18
1.6 本章小結 / 21
第二部分 自動記憶體管理機制
第2章 Java記憶體區域與記憶體溢出異常 / 24
2.1 概述 / 24
2.2 運行時數據區域 / 25
2.2.1 程式計數器 / 25
2.2.2 Java虛擬機棧 / 26
2.2.3 本地方法棧 / 27
2.2.4 Java堆 / 27
2.2.5 方法區 / 28
2.2.6 運行時常量池 / 29
2.2.7 直接記憶體 / 29
2.3 對象訪問 / 30
2.4 實戰:OutOfMemoryError異常 / 32
2.4.1 Java堆溢出 / 32
2.4.2 虛擬機棧和本地方法棧溢出 / 35
2.4.3 運行時常量池溢出 / 38
2.4.4 方法區溢出 / 39
2.4.5 本機直接記憶體溢出 / 41
2.5 本章小結 / 42
第3章 垃圾收集器與記憶體分配策略 / 43
3.1 概述 / 43
3.2 對象已死? / 44
3.2.1 引用計數算法 / 44
3.2.2 根搜尋算法 / 46
3.2.3 再談引用 / 47
3.2.4 生存還是死亡? / 48
3.2.5 回收方法區 / 50
3.3 垃圾收集算法 / 51
3.3.1 標記 -清除算法 / 51
3.3.2 複製算法 / 52
3.3.3 標記-整理算法 / 54
3.3.4 分代收集算法 / 54
3.4 垃圾收集器 / 55
3.4.1 Serial收集器 / 56
3.4.2 ParNew收集器 / 57
3.4.3 Parallel Scavenge收集器 / 59
3.4.4 Serial Old收集器 / 60
3.4.5 Parallel Old收集器 / 61
3.4.6 CMS收集器 / 61
3.4.7 G1收集器 / 64
3.4.8 垃圾收集器參數總結 / 64
3.5 記憶體分配與回收策略 / 65
3.5.1 對象優先在Eden分配 / 66
3.5.2 大對象直接進入老年代 / 68
3.5.3 長期存活的對象將進入老年代 / 69
3.5.4 動態對象年齡判定 / 71
3.5.5 空間分配擔保 / 73
3.6 本章小結 / 75
第4章 虛擬機性能監控與故障處理工具 / 76
4.1 概述 / 76
4.2 JDK的命令行工具 / 76
4.2.1 jps:虛擬機進程狀況工具 / 79
4.2.2 jstat:虛擬機統計信息監視工具 / 80
4.2.3 jinfo:Java配置信息工具 / 82
4.2.4 jmap:Java記憶體映像工具 / 82
4.2.5 jhat:虛擬機堆轉儲快照分析工具 / 84
4.2.6 jstack:Java堆疊跟蹤工具 / 85
4.3 JDK的可視化工具 / 87
4.3.1 JConsole:Java監視與管理控制台 / 88
4.3.2 VisualVM:多合一故障處理工具 / 96
4.4 本章小結 / 105
第5章 調優案例分析與實戰 / 106
5.1 概述 / 106
5.2 案例分析 / 106
5.2.1 高性能硬體上的程式部署策略 / 106
5.2.2 集群間同步導致的記憶體溢出 / 109
5.2.3 堆外記憶體導致的溢出錯誤 / 110
5.2.4 外部命令導致系統緩慢 / 112
5.2.5 伺服器JVM進程崩潰 / 113
5.3 實戰:Eclipse運行速度調優 / 114
5.3.1 調優前的程式運行狀態 / 114
5.3.2 升級JDK 1.6的性能變化及兼容問題 / 117
5.3.3 編譯時間和類載入時間的最佳化 / 122
5.3.4 調整記憶體設定控制垃圾收集頻率 / 126
5.3.5 選擇收集器降低延遲 / 130
5.4 本章小結 / 133
第三部分 虛擬機執行子系統
第6章 類檔案結構 / 136
6.1 概述 / 136
6.2 無關性的基石 / 136
6.3 Class類檔案的結構 / 138
6.3.1 魔數與Class檔案的版本 / 139
6.3.2 常量池 / 141
6.3.3 訪問標誌 / 147
6.3.4 類索引、父類索引與接口索引集合 / 148
6.3.5 欄位表集合 / 149
6.3.6 方法表集合 / 153
6.3.7 屬性表集合 / 155
6.4 Class檔案結構的發展 / 168
6.5 本章小結 / 170
第7章 虛擬機類載入機制 / 171
7.1 概述 / 171
7.2 類載入的時機 / 172
7.3 類載入的過程 / 176
7.3.1 載入 / 176
7.3.2 驗證 / 178
7.3.3 準備 / 181
7.3.4 解析 / 182
7.3.5 初始化 / 186
7.4 類載入器 / 189
7.4.1 類與類載入器 / 189
7.4.2 雙親委派模型 / 191
7.4.3 破壞雙親委派模型 / 194
7.5 本章小結 / 197
第8章 虛擬機位元組碼執行引擎 / 198
8.1 概述 / 198
8.2 運行時棧幀結構 / 199
8.2.1 局部變數表 / 199
8.2.2 運算元棧 / 204
8.2.3 動態連線 / 206
8.2.4 方法返回地址 / 206
8.2.5 附加信息 / 207
8.3 方法調用 / 207
8.3.1 解析 / 207
8.3.2 分派 / 209
8.4 基於棧的位元組碼解釋執行引擎 / 221
8.4.1 解釋執行 / 221
8.4.2 基於棧的指令集與基於暫存器的指令集 / 223
8.4.3 基於棧的解釋器執行過程 / 224
8.5 本章小結 / 230
第9章 類載入及執行子系統的案例與實戰 / 231
9.1 概述 / 231
9.2 案例分析 / 231
9.2.1 Tomcat:正統的類載入器架構 / 232
9.2.2 OSGi:靈活的類載入器架構 / 235
9.2.3 位元組碼生成技術與動態代理的實現 / 238
9.2.4 Retrotranslator:跨越JDK版本 / 242
9.3 實戰:自己動手實現遠程執行功能 / 246
9.3.1 目標 / 246
9.3.2 思路 / 247
9.3.3 實現 / 248
9.3.4 驗證 / 255
9.4 本章小結 / 256
第四部分 程式編譯與代碼最佳化
第10章 早期(編譯期)最佳化 / 258
10.1 概述 / 258
10.2 Javac編譯器 / 259
10.2.1 Javac的源碼與調試 / 259
10.2.2 解析與填充符號表 / 262
10.2.3 註解處理器 / 264
10.2.4 語義分析與位元組碼生成 / 264
10.3 Java語法糖的味道 / 268
10.3.1 泛型與類型擦除 / 268
10.3.2 自動裝箱、拆箱與遍歷循環 / 273
10.3.3 條件編譯 / 275
10.4 實戰:插入式註解處理器 / 276
10.4.1 實戰目標 / 276
10.4.2 代碼實現 / 277
10.4.3 運行與測試 / 284
10.4.4 其他套用案例 / 286
10.5 本章小結 / 286
第11章 晚期(運行期)最佳化 / 287
11.1 概述 / 287
11.2 HotSpot虛擬機內的即時編譯器 / 288
11.2.1 解釋器與編譯器 / 288
11.2.2 編譯對象與觸發條件 / 291
11.2.3 編譯過程 / 294
11.2.4 查看與分析即時編譯結果 / 297
11.3 編譯最佳化技術 / 301
11.3.1 最佳化技術概覽 / 301
11.3.2 公共子表達式消除 / 305
11.3.3 數組邊界檢查消除 / 307
11.3.4 方法內聯 / 307
11.3.5 逃逸分析 / 309
11.4 Java與C/C++的編譯器對比 / 311
11.5 本章小結 / 313
第五部分 高效並發
第12章 Java記憶體模型與執行緒 / 316
12.1 概述 / 316
12.2 硬體的效率與一致性 / 317
12.3 Java記憶體模型 / 318
12.3.1 主記憶體與工作記憶體 / 319
12.3.2 記憶體間互動操作 / 320
12.3.3 對於volatile型變數的特殊規則 / 322
12.3.4 對於long和double型變數的特殊規則 / 327
12.3.5 原子性、可見性與有序性 / 328
12.3.6 先行發生原則 / 330
12.4 Java與執行緒 / 333
12.4.1 執行緒的實現 / 333
12.4.2 Java執行緒調度 / 337
12.4.3 狀態轉換 / 339
12.5 本章小結 / 341
第13章 執行緒安全與鎖最佳化 / 342
13.1 概述 / 342
13.2 執行緒安全 / 343
13.2.1 Java語言中的執行緒安全 / 343
13.2.2 執行緒安全的實現方法 / 348
13.3 鎖最佳化 / 356
13.3.1 自旋鎖與自適應自旋 / 356
13.3.2 鎖消除 / 357
13.3.3 鎖粗化 / 358
13.3.4 輕量級鎖 / 358
13.3.5 偏向鎖 / 361
13.4 本章小結 / 362
附錄A Java虛擬機家族 / 363
附錄B 虛擬機位元組碼指令表 / 366
附錄C HotSpot虛擬機主要參數表 / 372
附錄D 對象查詢語言(OQL)簡介 / 376
附錄E JDK歷史版本軌跡 / 383

相關詞條

熱門詞條

聯絡我們