揭秘Java虛擬機:JVM設計原理與實現

揭秘Java虛擬機:JVM設計原理與實現

《揭秘Java虛擬機:JVM設計原理與實現》是2017年電子工業出版社出版的圖書,作者是封亞飛。

內容簡介

《揭秘Java虛擬機:JVM設計原理與實現》從源碼角度解讀HotSpot的內部實現機制,本書主要包含三大部分——JVM數據結構設計與實現、執行引擎機制及記憶體分配模型。 數據結構部分包括Java位元組碼檔案格式、常量池解析、欄位解析、方法解析。每一部分都給出詳細的源碼實現分析,例如欄位解析一章,從源碼層面詳細分析了Java欄位重排、欄位繼承等關鍵機制。再如方法解析一章,給出了Java多態特性在源碼層面的實現方式。《揭秘Java虛擬機:JVM設計原理與實現》通過直接對原始碼的分析,從根本上梳理和澄清Java領域中的關鍵概念和機制。 執行引擎部分包括Java方法調用機制、棧幀創建機制、指令集架構與解釋器實現機制。這一話題是《揭秘Java虛擬機:JVM設計原理與實現》技術含量高的部分,需要讀者具備一定的彙編基礎。不過千萬不要被“彙編”這個詞給嚇著,其實在作者看來,彙編相比於高級語言而言,語法非常簡單,語義也十分清晰。執行引擎部分重點描述Java原始碼如何轉換為位元組碼,又如何從位元組碼轉換為機器指令從而能夠被物理CPU所執行的技術實現。同時詳細分析了Java函式堆疊的創建全過程,在源碼分析的過程中,帶領讀者從本質上理解到底什麼是Java函式堆疊和棧幀,以及棧幀內部的詳細結構。 記憶體分配部分主要包括類型創建與載入、對象實例創建與記憶體分配,例如new關鍵字的工作機制,import關鍵字的作用,再如java.lang.ClassLoader.loadClass()接口的本地實現機制。 《揭秘Java虛擬機:JVM設計原理與實現》並不是簡單地分析源碼實現,而是在描述HotSpot內部實現機制的同時,分析了HotSpot如此這般實現的技術必然性。讀者在閱讀《揭秘Java虛擬機:JVM設計原理與實現》的過程中,將會在很多地方看到作者本人的這種思考。

目錄

第1章 Java虛擬機概述 1

1.1 從機器語言到Java——詹爺,你好 1

1.2 兼容的選擇:一場生產力的革命 6

1.3 中間語言翻譯 10

1.3.1 從中間語言翻譯到機器碼 11

1.3.2 通過C程式翻譯 11

1.3.3 直接翻譯為機器碼 13

1.3.4 本地編譯 16

1.4 神奇的指令 18

1.4.1 常見彙編指令 20

1.4.2 JVM指令 21

1.5 本章總結 24

第2章 Java執行引擎工作原理:方法調用 25

2.1 方法調用 26

2.1.1 真實的機器調用 26

2.1.2 C語言函式調用 41

2.2 JVM的函式調用機制 47

2.3 函式指針 53

2.4 CallStub函式指針定義 60

2.5 _call_stub_entry例程 72

2.6 本章總結 115

第3章 Java數據結構與面向對象 117

3.1 從Java算法到數據結構 118

3.2 數據類型簡史 122

3.3 Java數據結構之偶然性 129

3.4 Java類型識別 132

3.4.1 class位元組碼概述 133

3.4.2 魔數與JVM內部的int類型 136

3.4.3 常量池與JVM內部對象模型 137

3.5 大端與小端 143

3.5.1 大端和小端的概念 146

3.5.2 大小端產生的本質原因 148

3.5.3 大小端驗證 149

3.5.4 大端和小端產生的場景 151

3.5.5 如何解決位元組序反轉 154

3.5.6 大小端問題的避免 156

3.5.7 JVM對位元組碼檔案的大小端處理 156

3.6 本章總結 159

第4章 Java位元組碼實戰 161

4.1 位元組碼格式初探 161

4.1.1 準備測試用例 162

4.1.2 使用javap命令分析位元組碼檔案 162

4.1.3 查看位元組碼二進制 165

4.2 魔數與版本 166

4.2.1 魔數 168

4.2.2 版本號 168

4.3 常量池 169

4.3.1 常量池的基本結構 169

4.3.2 JVM所定義的11種常量 170

4.3.3 常量池元素的複合結構 170

4.3.4 常量池的結束位置 172

4.3.5 常量池元素總數量 172

4.3.6 第一個常量池元素 173

4.3.7 第二個常量池元素 174

4.3.8 父類常量 174

4.3.9 變數型常量池元素 175

4.4 訪問標識與繼承信息 177

4.4.1 access_flags 177

4.4.2 this_class 178

4.4.3 super_class 179

4.4.4 interface 179

4.5 欄位信息 180

4.5.1 fields_count 180

4.5.2 field_info fields[fields_count] 181

4.6 方法信息 185

4.6.1 methods_count 185

4.6.2 method_info methods[methods_count] 185

4.7 本章回顧 205

第5章 常量池解析 206

5.1 常量池記憶體分配 208

5.1.1 常量池記憶體分配總體鏈路 209

5.1.2 記憶體分配 215

5.1.3 初始化記憶體 223

5.2 oop-klass模型 224

5.2.1 兩模型三維度 225

5.2.2 體系總覽 227

5.2.3 oop體系 229

5.2.4 klass體系 231

5.2.5 handle體系 234

5.2.6 oop、klass、handle的相互轉換 239

5.3 常量池klass模型(1) 244

5.3.1 klassKlass實例構建總鏈路 246

5.3.2 為klassOop申請記憶體 249

5.3.3 klassOop記憶體清零 253

5.3.4 初始化mark 253

5.3.5 初始化klassOop._metadata 258

5.3.6 初始化klass 259

5.3.7 自指 260

5.4 常量池klass模型(2) 261

5.4.1 constantPoolKlass模型構建 261

5.4.2 constantPoolOop與klass 264

5.4.3 klassKlass終結符 267

5.5 常量池解析 267

5.5.1 constantPoolOop域初始化 268

5.5.2 初始化tag 269

5.5.3 解析常量池元素 271

5.6 本章總結 279

第6章 類變數解析 280

6.1 類變數解析 281

6.2 偏移量 285

6.2.1 靜態變數偏移量 285

6.2.2 非靜態變數偏移量 287

6.2.3 Java欄位記憶體分配總結 312

6.3 從源碼看欄位繼承 319

6.3.1 欄位重排與補白 319

6.3.2 private欄位可被繼承嗎 325

6.3.3 使用HSDB驗證欄位分配與繼承 329

6.3.4 引用類型變數記憶體分配 338

6.4 本章總結 342

第7章 Java棧幀 344

7.1 entry_point例程生成 345

7.2 局部變數表創建 352

7.2.1 constMethod的記憶體布局 352

7.2.2 局部變數表空間計算 356

7.2.3 初始化局部變數區 359

7.3 堆疊與棧幀 368

7.3.1 棧幀是什麼 368

7.3.2 硬體對堆疊的支持 387

7.3.3 棧幀開闢與回收 390

7.3.4 堆疊大小與多執行緒 391

7.4 JVM的棧幀 396

7.4.1 JVM棧幀與大小確定 396

7.4.2 棧幀創建 399

7.4.3 局部變數表 421

7.5 棧幀深度與slot復用 433

7.6 最大運算元棧與運算元棧復用 436

7.7 本章總結 439

第8章 類方法解析 440

8.1 方法簽名解析與校驗 445

8.2 方法屬性解析 447

8.2.1 code屬性解析 447

8.2.2 LVT&LVTT 449

8.3 創建methodOop 455

8.4 Java方法屬性複製 459

8.5 與 461

8.6 查看運行時位元組碼指令 482

8.7 vtable 489

8.7.1 多態 489

8.7.2 C++中的多態與vtable 491

8.7.3 Java中的多態實現機制 493

8.7.4 vtable與invokevirtual指令 500

8.7.5 HSDB查看運行時vtable 502

8.7.6 miranda方法 505

8.7.7 vtable特點總結 508

8.7.8 vtable機制邏輯驗證 509

8.8 本章總結 511

第9章 執行引擎 513

9.1 執行引擎概述 514

9.2 取指 516

9.2.1 指令長度 519

9.2.2 JVM的兩級取指機制 527

9.2.3 取指指令放在哪 532

9.2.4 程式計數器在哪裡 534

9.3 解碼 535

9.3.1 模板表 535

9.3.2 彙編器 540

9.3.3 彙編 549

9.4 棧頂快取 558

9.5 棧式指令集 565

9.6 運算元棧在哪裡 576

9.7 棧幀重疊 581

9.8 entry_point例程機器指令 586

9.9 執行引擎實戰 588

9.9.1 一個簡單的例子 588

9.9.2 位元組碼運行過程分析 590

9.10 位元組碼指令實現 597

9.10.1 iconst_3 598

9.10.2 istore_0 599

9.10.3 iadd 600

9.11 本章總結 601

第10章 類的生命周期 602

10.1 類的生命周期概述 602

10.2 類載入 605

10.2.1 類載入——鏡像類與靜態欄位 611

10.2.2 Java主類載入機制 617

10.2.3 類載入器的載入機制 622

10.2.4 反射載入機制 623

10.2.5 import與new指令 624

10.3 類的初始化 625

10.4 類載入器 628

10.4.1 類載入器的定義 628

10.4.2 系統類載入器與擴展類載入器創建 634

10.4.3 雙親委派機制與破壞 636

10.4.4 預載入 638

10.4.5 引導類載入 640

10.4.6 載入、連結與延遲載入 641

10.4.7 父載入器 645

10.4.8 載入器與類型轉換 648

10.5 類實例分配 649

10.5.1 棧上分配與逃逸分析 652

10.5.2 TLAB 655

10.5.3 指針碰撞與eden區分配 657

10.5.4 清零 658

10.5.5 偏向鎖 658

10.5.6 壓棧與取指 659

10.6 本章總結 661

相關詞條

熱門詞條

聯絡我們