大佬帶你深入理解Java虛擬機: JVM高級特性與最佳實踐(第3版)速領

前言

Java是目前用戶最多、使用範圍最廣的軟件開發技術,Java的技 術體系主要由支撐Java程序運行的虛擬機、提供各開發領域接口支持的Java類庫、 Java編程語言及許許多多的第三方Java框架(如Spring、 MyBatis等) 構成。在國內,有關Java類庫API Java語言語法及第三方框架的技術資料和書籍非常豐富,相比而言,有關Java虛擬機的資料卻顯得異常貧乏。

這種狀況很大程度上是由Java開發技術本身的一個重要優點導致的:在虛擬機層面隱藏了底層技術的複雜性以及機器與操作系統的差異性。運行程序的物理機千差萬別,而Java虛擬機則在千差萬別的物理機上面建立了統一 -的運行平臺,實現了在任意一臺Java虛擬機上編譯的程序,都能在任何其他Java虛擬機上正常運行。這一 極大的優勢使得Java應用的開發比傳統CIC++應用的開發更高效快捷,程序員可以把主要精力放在具體業務邏輯,而不是放在保障物理硬件的兼容性上。通常情況下,一個程序員只要瞭解了必要的Java類庫API、 Java語法, 學習適當的第三方開發框架,就已經基本滿足日常開發的需要了。虛擬機會在用戶不知不覺中完成對硬件平臺的兼容及對內存等資源的管理工作。因此,瞭解虛擬機的運作並不是普通開發人員必備的,或者說首要學習的知識。

然而,凡事都具備兩面性。隨著Java技術的不斷髮展,它已被應用於越來越多的領域之中。其中一些領域,如互聯網、能源、金融、通信等,對程序的性能、穩定性和擴展性方面會有極高的要求。

一段程序很可能在10個人同時使用時完全正常,但是在1000個人同時使用時就會緩慢、死鎖甚至崩潰。毫無疑問,要滿足1000個人同時使用,需要更高性能的物理硬件,但是在絕大多數情況下,提升硬件性能無法等比例提升程序的運行性能和併發能力,甚至有可能對程序運行狀況沒有任何改善。這裡面有Java虛擬機的原因:為了達到“所有硬件提供- -致的虛擬平臺”的目的,犧牲了一些硬件相關的性能特性。更重要的是人為原因:如果開發人員不瞭解虛擬機諸多技術特性的運行原理,就無法寫出最適合虛擬機運行和自優化的代碼。

其實,目前商用的高性能Java虛擬機都提供了相當多的優化參數和調節手段,用於滿足應用程序在實際生產環境中對性能和穩定性的要求。如果只是為了入門學習,讓程序在自己的機器上正常工作,那麼這些特性可以說是可有可無的:但是,如果用於生產開發,尤其是大規模的、企業級的生產開發,就迫切需要開發人員中至少有一-部分人對虛擬機的特性及調節方法具有很清晰的認識。所以在Java開發體系中,對架構師、系統調優師、高級程序員等角色的需求一 直都非常大。學習虛擬機中各種自動運作特性的原理也成為Java程序員成長路上最終必然會接觸到的一課。通過本書,讀者可以以個相對輕鬆的方式學到虛擬機的運作原理。

本篇內容主要分為五部分13章的內容,下面是具體內容的介紹目錄,大家可以一目瞭然。

第一部分 走近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 本章小結


大佬帶你深入理解Java虛擬機: JVM高級特性與最佳實踐(第3版)速領


本技術文檔根據JDK新版本全面升級,新增內容近50%,從Java技術體系、自動內存管理、虛擬機執行子系統、程序編譯與代碼優化、高效併發5個維度全面分析JVM。

需要本技術文檔的小夥伴,轉發關注小編,私信小編“學習”來得到獲取方式哦~~~~


分享到:


相關文章: