国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM)

這篇具有很好參考價(jià)值的文章主要介紹了一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1. JVM 概述

JVMJava Virtual Machine,也就是 Java 虛擬機(jī)

所謂虛擬機(jī)是指:通過(guò)軟件模擬的具有完整硬件系統(tǒng)功能的、運(yùn)行在一個(gè)完全隔離環(huán)境中的計(jì)算機(jī)系統(tǒng)。

即:虛擬機(jī)是一個(gè)計(jì)算機(jī)系統(tǒng)。這種計(jì)算機(jī)系統(tǒng)運(yùn)行在完全隔離的環(huán)境中,且它的硬件系統(tǒng)功能是通過(guò)軟件模擬出來(lái)的。

JVM 通過(guò)軟件來(lái)模擬 Java 字節(jié)碼的指令集,是 Java 程序的運(yùn)行環(huán)境。

1.1 JVM 的主要功能

JVM 的主要功能包括:

  1. 通過(guò) ClassLoader 尋找和裝載 class 文件;
  2. 解釋字節(jié)碼成為指令,并執(zhí)行,同時(shí)提供 class 文件的運(yùn)行環(huán)境;
  3. 進(jìn)行運(yùn)行期間的內(nèi)存分配和垃圾回收;
  4. 提供與硬件交互的平臺(tái)。
    一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

1.2 虛擬機(jī)是 Java 平臺(tái)無(wú)關(guān)的保障

Java 程序只跟 Java 虛擬機(jī)相關(guān),跟平臺(tái)無(wú)關(guān)。

跟平臺(tái)相關(guān)的是 Java 虛擬機(jī)本身。
一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

2. JVM 規(guī)范的作用

Java 虛擬機(jī)規(guī)范為不同的硬件平臺(tái)提供了一種編譯 Java 技術(shù)代碼的規(guī)范。

JVM 規(guī)范只是對(duì)編譯出來(lái)的 class 字節(jié)碼文件進(jìn)行規(guī)范,而并沒(méi)有對(duì) Java 源文件進(jìn)行規(guī)范。

也就是說(shuō) Java 虛擬機(jī)只認(rèn) class 字節(jié)碼文件,不認(rèn) Java 源文件。

Java 虛擬機(jī)不關(guān)心 class 字節(jié)碼文件是怎么來(lái)的 ,只關(guān)心 class 字節(jié)碼文件符不符合 JVM 規(guī)范。

即使開(kāi)發(fā)語(yǔ)言不是 Java,只要能編譯生成符合 JVM 規(guī)范的 class 字節(jié)碼文件,那么這種開(kāi)發(fā)語(yǔ)言也是可以使用的。

Java 虛擬機(jī)不僅實(shí)現(xiàn)了平臺(tái)無(wú)關(guān),也實(shí)現(xiàn)了開(kāi)發(fā)語(yǔ)言無(wú)關(guān)。
一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

JVM 規(guī)范使 Java 軟件獨(dú)立于平臺(tái),因?yàn)榫幾g是針對(duì)作為虛擬機(jī)的 “一般機(jī)器” 而做。

這個(gè)作為虛擬機(jī)的 “一般機(jī)器” 可以是用軟件模擬并運(yùn)行于各種現(xiàn)存的計(jì)算機(jī)系統(tǒng);也可以是用硬件來(lái)實(shí)現(xiàn)。

JVM 規(guī)范只是對(duì) Java 虛擬機(jī)的實(shí)現(xiàn)提出了一些必須遵循的要求,并沒(méi)有規(guī)定如何去實(shí)現(xiàn) Java 虛擬機(jī)。因此,不同廠商實(shí)現(xiàn)的 Java 虛擬機(jī)可能是不同的。

3. JVM 規(guī)范文檔的下載獲取

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

Java 8 版本的虛擬機(jī)在網(wǎng)上有中文版的。

Java 8Java 13 版本的 JVM 規(guī)范文檔基本上是一樣的(在 Java 13 版本中的第 5 章多出了 Module 小節(jié))。

4. JVM 規(guī)范中的主要內(nèi)容

這里介紹 Java SE8 虛擬機(jī)規(guī)范文檔(中文版)中的主要內(nèi)容:

  1. 字節(jié)碼指令集(相當(dāng)于中央處理器 CPU
  2. Class 文件的格式
  3. 數(shù)據(jù)類型和值
  4. 運(yùn)行時(shí)數(shù)據(jù)區(qū)
  5. 棧幀
  6. 特殊方法
  7. 類庫(kù)
  8. 異常
  9. 虛擬機(jī)的啟動(dòng)、加載、鏈接和初始化

4.1 字節(jié)碼指令集

class 字節(jié)碼指令集的相關(guān)內(nèi)容可參考 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 中的第 2.11 節(jié)、第 6 章、第 7 章。
一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

詳見(jiàn) 5. 字節(jié)碼指令集

4.2 Class 文件的格式

參考 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 中第 4 章內(nèi)容

詳見(jiàn) 8. Class 文件的格式

4.3 數(shù)據(jù)類型和值

參考 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 中第 2.2、2.3、2.4 節(jié)內(nèi)容
一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

4.4 運(yùn)行時(shí)數(shù)據(jù)區(qū)

參考 《內(nèi)存分配》 中的 運(yùn)行時(shí)數(shù)據(jù)區(qū)

4.5 棧幀

參考本文章中的 棧幀

參考 《內(nèi)存分配》 中的 Java

參考 《字節(jié)碼執(zhí)行引擎》 中的 棧幀

4.6 特殊方法

參考 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 中第 2.9 節(jié)內(nèi)容

詳見(jiàn) 6. 特殊方法

4.7 類庫(kù)

詳見(jiàn) 7. 類庫(kù)

4.8 異常

參考 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 中第 2.10 節(jié)內(nèi)容

4.9 虛擬機(jī)的啟動(dòng)、加載、鏈接和初始化

參考 《類加載、連接和初始化》

5. 字節(jié)碼指令集

5.1 字節(jié)碼指令集簡(jiǎn)介

Java 虛擬機(jī)的指令由一個(gè)字節(jié)長(zhǎng)度的、代表著某種特定操作含義的 操作碼opcode)以及跟隨其后的 0 至多個(gè)代表此操作所需參數(shù)的 操作數(shù)operand)所構(gòu)成。

虛擬機(jī)中許多指令并不包含操作數(shù),只有一個(gè)操作碼。

我們常說(shuō)的字節(jié)碼指令其實(shí)就是這里的操作碼。

5.2 數(shù)據(jù)類型與指令集

JVM 根據(jù)不同的數(shù)據(jù)類型提供不同的字節(jié)碼指令。

如下表所示:

第 1 列的 Txxx 中的 T 相當(dāng)于泛型參數(shù),
即數(shù)據(jù)類型不同,T 的取值不同。如:對(duì) byte 類型,Tipush 即為 bipush

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.3 加載和存儲(chǔ)指令

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.4 算術(shù)指令

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.5 類型轉(zhuǎn)換指令

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.6 對(duì)象的創(chuàng)建與操作指令

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.7 操作數(shù)棧管理指令

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.8 控制轉(zhuǎn)移指令

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.9 方法調(diào)用和返回指令

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.10 拋出異常相關(guān)的指令

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.11 同步相關(guān)的指令

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.12 指令格式表(描述指令的功能,使用方式等)

通過(guò)指令格式表對(duì)指令進(jìn)行描述,告訴你如何使用指令,指令格式表如下圖所示:

指令格式表中描述了指令的功能,使用方式,注意事項(xiàng)等。

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

上表中,助記符就是字節(jié)碼指令(助記符是給人看的)。操作碼就是字節(jié)碼指令對(duì)應(yīng)的編碼(給機(jī)器識(shí)別的)。

指令集中的指令都會(huì)以上表為模板進(jìn)行描述。

如何閱讀指令格式表

下面舉例說(shuō)明如何閱讀指令格式表中對(duì)指令的描述。

實(shí)際開(kāi)發(fā)中,可以在 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 中第 6.5 節(jié)中查找具體指令的格式表

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM
一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

5.13 如何用字節(jié)碼指令集表示 Java 代碼

如果對(duì)某些字節(jié)碼指令不知道什么時(shí)候用到,可以參數(shù) 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 中第 3 章的內(nèi)容,查看字節(jié)碼指令對(duì)應(yīng)的 Java 代碼是什么樣的。

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

6. 特殊方法

6.1 <init>

實(shí)例初始化方法,通過(guò) JVMinvokespecial 指令 來(lái)調(diào)用

<init> 方法并不是指 Java 代碼中定義的構(gòu)造方法。

Java 代碼中定義的構(gòu)造方法可以理解成是 JVM 在執(zhí)行完 <init> 方法,創(chuàng)建了實(shí)例對(duì)象之后,給程序員提供的一種回調(diào)方法。

6.2 <clinit>

類或接口的初始化方法,不包含參數(shù),返回 void

7. 類庫(kù)

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8. Class 文件的格式

8.1 Class 文件概述

Class 文件是 JVM 的輸入;是 JVM 實(shí)現(xiàn)平臺(tái)無(wú)關(guān)、語(yǔ)言無(wú)關(guān)的基礎(chǔ)。

Java 虛擬機(jī)規(guī)范中定義了 Class 文件的結(jié)構(gòu)(參考 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 中第 4 章內(nèi)容)。

Class 文件是一組以 8 字節(jié)為單位的字節(jié)流。文件中的各個(gè)數(shù)據(jù)項(xiàng)目按指定的順序緊湊排列。

對(duì)于占用空間大于 8 字節(jié)的數(shù)據(jù)項(xiàng),按照高位在前的方式分割成多個(gè) 8 字節(jié)進(jìn)行存儲(chǔ)。

8.2 Class 文件中的兩種類型(無(wú)符號(hào)數(shù)、表)

總的來(lái)說(shuō),Class 文件中只有兩種類型:

  1. 無(wú)符號(hào)數(shù): 即基本數(shù)據(jù)類型。以 u1、u2u4、u8 來(lái)代表幾個(gè)字節(jié)的無(wú)符號(hào)數(shù)。

    u1 代表 1 字節(jié)的無(wú)符號(hào)數(shù),…,u8 代表 8 字節(jié)的無(wú)符號(hào)數(shù)。

  2. 表: 由多個(gè)無(wú)符號(hào)數(shù)和其他表構(gòu)成的復(fù)合數(shù)據(jù)類型。通常以 “_info” 結(jié)尾。

8.3 ClassFile 結(jié)構(gòu)

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.4 查看 Java 源碼對(duì)應(yīng)的 Class 字節(jié)碼文件的三種方式

8.4.1 在 Eclipse 中查看 class 文件

EclipseNavigator 視圖中找到 class 文件,打開(kāi)查看即可。

此方式查看的 class 文件不完整。

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.4.2 通過(guò) javap 命令查看 class 文件

class 文件所在的 bin 目錄下執(zhí)行 “javap -verbose 全路徑類名” 查看 class 文件。

此方式查看的 class 文件是完整的。

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

javap 生成的非正式 “虛擬機(jī)匯編語(yǔ)言” 的格式:

通過(guò) javap 查看 class 文件時(shí),對(duì)于類中成員方法的方法體代碼,采用非正式 “虛擬機(jī)匯編語(yǔ)言” 進(jìn)行描述。格式如下:

<index> <opcode> [<operand1> [<operand2> ...]] [<comment>]
其中:
<index> 是指令操作碼在 code[] 數(shù)組中的索引,code[] 數(shù)組以字節(jié)形式來(lái)存儲(chǔ)當(dāng)前分發(fā)的 `Java` 虛擬機(jī)代碼;
        也可以是相對(duì)于方法起始處的字節(jié)偏移量
<opcode> 是指令的操作碼
<operand> 是操作數(shù)
<comment> 是行尾的注釋

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

如上圖中的 main 方法所示:

對(duì)于 0: getstatic   #23   // Field java/lang/System.out:Ljava/io/PrintStream; 
其中:
<index> 就是 0
<opcode> 就是助記符 getstatic(用于獲取類的靜態(tài)字段值)
<operand> 只有一個(gè),就是 #23(表示 Constant Pool 常量池中的編號(hào))
<comment> 就是 // 后面的內(nèi)容
這條非正式 “虛擬機(jī)匯編語(yǔ)言” 的含義就是:將靜態(tài)字段值 System.out 插入到操作數(shù)棧的棧頂
8.4.3 通過(guò) 16 進(jìn)制文件查看工具(如 winhex)查看 class 文件

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

參考 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 第 4.1 節(jié)內(nèi)容,結(jié)合 ClassFile 結(jié)構(gòu),對(duì) winhex 中顯示的 Hello.class 文件的 16 進(jìn)制數(shù)據(jù)分析如下:

1. 最開(kāi)始的 4 字節(jié)(u4)是 magic(魔數(shù)),JVM 規(guī)范要求固定為 0xCAFEBABE
2. 接下來(lái)的 2 字節(jié)(u2)是 minor_version(副版本號(hào)),即 0x0000,對(duì)應(yīng)十進(jìn)制 0
3. 接下來(lái)的 2 字節(jié)(u2)是 major_version(主版本號(hào)),即 0x0034,對(duì)應(yīng)十進(jìn)制 16*3+4 = 52
    因?yàn)?JDK 版本為 1.k(k>=2)時(shí),對(duì)應(yīng)的 class 文件版本號(hào)范圍是 45.0 ~ 44+k.0,所以這里的版本號(hào)是 1.8.0(44+8 = 52)
4. 接下來(lái)的 2 字節(jié)(u2)是 constant_pool_count,表示常量池的大小,即 0x0035,對(duì)應(yīng)十進(jìn)制 53
    注意:常量池的大小不是指常量池所占的內(nèi)存字節(jié)數(shù),而是指常量池中的成員個(gè)數(shù)。
    常量池中的成員索引為 [0, constant_pool_count - 1],
    常量池中的 #0 不是一個(gè)有效的常量池項(xiàng),僅用來(lái)表示 “不引用任何一個(gè)常量池項(xiàng)”。
    也就是說(shuō),當(dāng) constant_pool_count = 53 時(shí),常量池中有效的常量索引為 #1 ~ #52

8.5 常量池

Java 虛擬機(jī)指令不依賴于類、接口、類的實(shí)例對(duì)象、或數(shù)組的運(yùn)行時(shí)布局,而是依賴常量池表中的符號(hào)信息。

即通過(guò)指令集中的指令來(lái)描述 Java 代碼時(shí),需要依賴 class 文件中常量池內(nèi)保存的符號(hào)信息。

8.5.1 常量池項(xiàng)在 class 文件中的通用格式

常量池表中的所有的項(xiàng)都具有如下通用格式:

cp_info {
    u1 tag;
    u2 info[];
}

常量池表中,一個(gè) cp_info 表示一個(gè)常量池項(xiàng),ClassFile 結(jié)構(gòu)中的常量池?cái)?shù)組就是由多個(gè) cp_info 構(gòu)成的。

常量池表中,存在多個(gè)不同類型的 cp_info(常量池項(xiàng))。

cp_info 中占 1 字節(jié)(u1)的 tag 表示 cp_info 的類型。

tag 不同,cp_info 成員結(jié)構(gòu)(info[])也不同,cp_info 所占的內(nèi)存大小也不同。

注意:通用格式中的 “u1 info[]” 并不是說(shuō) cp_infotag 之后 info 數(shù)組只占 1 字節(jié)。

u1 info[]” 沒(méi)有明確的含義,必須根據(jù)不同的 tag 值,才能確定 info[] 表示的成員結(jié)構(gòu)和所占的內(nèi)存大小。

8.5.2 常量池項(xiàng)的類型(tag

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

上圖所示的表中給出了 cp_info 常量池項(xiàng)的不同 tag 類型,以及對(duì)應(yīng)的 tag 數(shù)值。

8.5.2.1 CONSTANT_Class_info 類型

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.5.2.2 CONSTANT_Fieldref_info 類型
8.5.2.3 CONSTANT_Methodref_info 類型
8.5.2.4 CONSTANT_InterfaceMethodref_info 類型

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.5.2.5 CONSTANT_String_info 類型

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.5.2.6 CONSTANT_Integer_info 類型
8.5.2.7 CONSTANT_Float_info 類型

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.5.2.8 CONSTANT_Long_info 類型
8.5.2.9 CONSTANT_Double_info 類型

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.5.2.10 CONSTANT_NameAndType_info 類型

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.5.2.11 CONSTANT_Utf8_info 類型

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.5.2.12 CONSTANT_MethodHandle_info 類型

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.5.2.13 CONSTANT_MethodType_info 類型

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.5.2.14 CONSTANT_InvokeDynamic_info 類型

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.5.3 如何確定 class 文件中常量池的結(jié)束位置

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.6 access_flags(訪問(wèn)權(quán)限標(biāo)志)

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.7 this_class、super_class、interfaces

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM
一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.8 字段(成員變量)

每個(gè)字段(field)都通過(guò) field_info 結(jié)構(gòu)定義。

8.8.1 字段在 class 文件中的格式
field_info {
    u2              access_flags;
    u2              name_index;
    u2              descriptor_index;
    u2              attributes_count;
    attribute_info  attributes[attributes_count];
}

其中:
access_flags:表示字段的訪問(wèn)權(quán)限和基本屬性。可以是多個(gè)權(quán)限和屬性的標(biāo)志的組合(位或運(yùn)算)。
name_index:是對(duì)常量池表的一個(gè)有效索引,該索引指向的常量池項(xiàng)的類型為 CONSTANT_Utf8_info,用于表示字段名。
descriptor_index:是對(duì)常量池表的一個(gè)有效索引,該索引指向的常量池項(xiàng)的類型為 CONSTANT_Utf8_info,用于表示字段描述符。
attributes_count:表示當(dāng)前字段的附加屬性的數(shù)量。
attributes[]:表示附加屬性表,表中每個(gè)附加屬性的結(jié)構(gòu)必須是 attribute_info。
字段描述符

字段的描述符(descriptor)是一個(gè)用于 描述字段類型 的字符串。

字段描述符不僅可以描述成員變量的類型,還可以描述靜態(tài)變量和局部變量的類型。

即:字段描述符就是用來(lái)描述任意變量的類型的。

參考 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 第 4.3.2 節(jié)(字段描述符)內(nèi)容。

// 字段描述符用于描述字段類型
FieldDescriptor:
    FieldType

// 字段類型包括:基本類型、類類型、數(shù)組類型
FieldType:
    BaseType
    ObjectType
    ArrayType

// 基本類型就是 byte/char/double/float/int/long/short/boolean 其中之一。
BaseType: one of
    B C D F I J S Z

// 類類型就是 "L + 全路徑類名(路徑中的 "." 用 "/" 代替) + ;"
ObjectType:
    L<ClassName>;

// 數(shù)組類型就是 "[ + 元素類型"
ArrayType:
    [<ComponentType>

// 數(shù)組的元素類型就是 字段類型
ComponentType:
    FieldType

字段描述符解釋表如下:

FieldType 中的字符 類型 含義
B byte 字節(jié)型數(shù)
C char 字符型數(shù)
D double 雙精度浮點(diǎn)數(shù)
F float 單精度浮點(diǎn)數(shù)
I int 整型數(shù)
J long 長(zhǎng)整數(shù)
L<ClassName> reference ClassName 類的實(shí)例
S short 短整數(shù)
Z boolean 布爾值 true/false
[ reference 一個(gè)一維數(shù)組

特別注意:基本類型中,long 的描述符為 Jboolean 的描述符為 Z,其他基本類型的描述符即為大寫的首字母。

舉例:

int 變量的描述符是:I
Object 類型的實(shí)例變量的描述符是:Ljava/lang/Object;
三維數(shù)組 double d[][][] 類型的變量的描述符是:[[[D
8.8.2 字段的訪問(wèn)權(quán)限和基本屬性的標(biāo)志

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

字段的各個(gè)訪問(wèn)標(biāo)志是可以通過(guò)位或運(yùn)算進(jìn)行組合的。

private static 修飾的字段就是 ACC_PRIVATEACC_STATIC 的組合,此時(shí) access_flags 的值就是 0x0002 | 0x0008 = 0x000A

8.8.3 字段在 class 文件中的解析舉例

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.9 方法(成員方法)

包括實(shí)例初始化方法以及類或接口初始化方法在內(nèi)的所有方法(method),都通過(guò) method_info 結(jié)構(gòu)來(lái)定義。

8.9.1 方法在 class 文件中的格式
method_info {
    u2              access_flags;
    u2              name_index;
    u2              descriptor_index;
    u2              attributes_count;
    attribute_info  attributes[attributes_count];
}

其中:
access_flags:表示方法的訪問(wèn)權(quán)限和基本屬性??梢允嵌鄠€(gè)權(quán)限和屬性的標(biāo)志的組合(位或運(yùn)算)。
name_index:是對(duì)常量池表的一個(gè)有效索引,該索引指向的常量池項(xiàng)的類型為 CONSTANT_Utf8_info,用于表示方法名。
descriptor_index:是對(duì)常量池表的一個(gè)有效索引,該索引指向的常量池項(xiàng)的類型為 CONSTANT_Utf8_info,用于表示方法描述符。
attributes_count:表示當(dāng)前方法的附加屬性的數(shù)量。
attributes[]:表示附加屬性表,表中每個(gè)附加屬性的結(jié)構(gòu)必須是 attribute_info。
方法描述符

方法描述符(descriptor)是一個(gè)用于 描述參數(shù)類型和返回值類型 的字符串。

無(wú)論某方法是靜態(tài)方法還是實(shí)例方法,其方法描述符都是相同的。

也就是說(shuō)無(wú)法通過(guò)一個(gè)方法的方法描述符來(lái)判斷該方法是靜態(tài)的還是非靜態(tài)的。

盡管實(shí)例方法除了傳遞自身定義的參數(shù)外,還需要額外傳遞參數(shù) this,但是這一點(diǎn)不是由方法描述符來(lái)表達(dá)的。

參數(shù) this 的傳遞是由 Java 虛擬機(jī)中調(diào)用實(shí)例方法時(shí)所使用的字節(jié)碼指令來(lái)實(shí)現(xiàn)的。

參考 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 第 4.3.3 節(jié)(方法描述符)內(nèi)容。

// 方法描述符由參數(shù)描述符列表和返回值描述符組成
MethodDescriptor:
    ({ParameterDescriptor})ReturnDescriptor

// 參數(shù)描述符就是 字段類型
ParameterDescriptor:
    FieldType

// 返回值描述符包括: 字段類型、void 描述符
ReturnDescriptor:
    FieldType
    VoidDescriptor

// void 描述符就是 V,表示方法不返回任何值(即方法的返回值類型是 void)
VoidDescriptor:
    V

舉例:

Object foo(int i, double d, Thread t) {...} 方法的描述符是:(IDLjava/lang/Thread;)Ljava/lang/Object;
void foo() {...} 方法的描述符是:()V
8.9.2 方法在 class 文件中的解析舉例

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.10 屬性(attribute)

屬性(attribute)在 class 文件中的 ClassFile 結(jié)構(gòu)、field_info 結(jié)構(gòu)、method_info 結(jié)構(gòu)和 Code_attribute 結(jié)構(gòu)中都有使用。

8.10.1 屬性在 class 文件中的通用格式
attribute_info {
    u2 attribute_name_index;
    u4 attribute_length;
    u1 info[attribute_length];
}

其中:
attribute_name_index:是對(duì)常量池表的一個(gè)有效索引,該索引指向的常量池項(xiàng)的類型為 CONSTANT_Utf8_info,用于表示屬性名。
attribute_length:給出了 info[] 數(shù)組所占的字節(jié)大小。
info[]:不同屬性的 info[] 不同,參考各個(gè)屬性的具體格式。
8.10.2 JVM 規(guī)范中預(yù)定義的屬性(23 個(gè))

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.10.3 Code 屬性

Code 屬性附加方法的附加屬性出現(xiàn)在 method_info 結(jié)構(gòu)中。

Code 屬性中包含方法(如成員方法、實(shí)例初始化方法、類或接口初始化方法)的 Java 虛擬機(jī)指令,及相關(guān)的輔助信息。

對(duì)于抽象方法(abstract 修飾的方法)、本地方法(native 修飾的方法),方法對(duì)應(yīng)的 method_info 結(jié)構(gòu)中不能有 Code 屬性。

native、abstract 方法之外的其他方法的 method_info 中則必須有,且只能有一個(gè) Code 屬性。

8.10.3.1 Code 屬性的格式
Code_attribute {
    u2             attribute_name_index;
    u4             attribute_length;
    u2             max_stack;
    u2             max_locals;
    u4             code_length;
    u1             code[code_length];
    u2             exception_table_length;

    {
        u2 start_pc;
        u2 end_pc;
        u2 handler_pc;
        u2 catch_type;
    } exception_table[exception_table_length];

    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

其中:
attribute_name_index:是對(duì)常量池表的一個(gè)有效索引,該索引指向的常量池項(xiàng)的類型為 CONSTANT_Utf8_info,固定為屬性名 `Code`。
attribute_length:表示從 max_stack 到 attribute_info_attributes[] 所占的字節(jié)大小。即當(dāng)前 Code 屬性在 class 文件中的剩余長(zhǎng)度。
max_stack:表示當(dāng)前方法在調(diào)用時(shí),其棧幀中的操作數(shù)棧的最大深度。
max_locals:表示當(dāng)前方法在調(diào)用時(shí),其棧幀中的局部變量表內(nèi),有多少個(gè)局部變量(包括用于傳遞參數(shù)的局部變量)。
code_length:表示 code[] 數(shù)組所占的字節(jié)大小。(code_length 的值必須大于 0 ,即 code[] 數(shù)組不能為空)
code[]:用于保存實(shí)現(xiàn)當(dāng)前方法的 `Java` 虛擬機(jī)代碼。
exception_table_length:表示 exception_table[] 數(shù)組中的元素個(gè)數(shù)。

exception_table[]:該數(shù)組中的一個(gè)元素代表 code[] 數(shù)組中的一個(gè)異常處理器。
exception_table[] 數(shù)組中的每個(gè)元素都包含如下結(jié)構(gòu):
    start_pc 和 end_pc:當(dāng)前元素代表的異常處理器在 code[] 中的有效范圍是 [start_pc, end_pc]。
                        start_pc 的值表示對(duì) code[] 中某一指令操作碼的有效索引;
                        end_pc 的值要么是對(duì) code[] 中某一指令操作碼的有效索引,要么等于 code_length;
                        start_pc 必須小于 end_pc。
                        當(dāng)程序計(jì)數(shù)器在范圍 [start_pc, end_pc] 內(nèi)時(shí),當(dāng)前元素表示的異常處理器就將生效。
    handler_pc:當(dāng)前元素代表的異常處理器的起點(diǎn),handler_pc 的值表示對(duì) code[] 中某一指令操作碼的有效索引。
    catch_type:若值不為 0,
                    則表示對(duì)常量池表的一個(gè)有效索引,該索引指向的常量池項(xiàng)的類型為 CONSTANT_Class_info,
                    表示當(dāng)前元素代表的異常處理器需要捕捉的異常類型。
                若值為 0,
                    則表示當(dāng)任意異常拋出時(shí),都會(huì)調(diào)用當(dāng)前元素代表的異常處理器。
                    這可用于實(shí)現(xiàn) finally 語(yǔ)句。

attributes_count:表示 attributes[] 數(shù)組中的元素個(gè)數(shù)。
attributes[]:表示與 Code 屬性相關(guān)聯(lián)的其他附加屬性的集合。
              該數(shù)組(屬性表)中的每個(gè)元素都必須是 attribute_info 類型的。

Code 屬性相關(guān)聯(lián)的附加屬性(即 attributes[] 屬性表中的屬性類型)可以是:

  1. LineNumberTable
  2. LocalVariableTable
  3. LocalVariableTypeTable
  4. StackMapTable
  5. RuntimeVisibleTypeAnnotationsRuntimeInvisisbleTypeAnnotations
8.10.3.2 LineNumberTable
該屬性用于確定 Java 源碼與 code[] 中的 `Java` 虛擬機(jī)代碼之間的對(duì)應(yīng)關(guān)系。
LineNumberTable 屬性中保存了一個(gè) line_number_table[] 數(shù)組,該數(shù)組元素的結(jié)構(gòu)為:
    {
        u2 start_pc;
        u2 line_number;
    }
通過(guò)數(shù)組元素可以表明:
    Java 源文件中行號(hào)為 line_number 處的源碼,會(huì)在 code[] 數(shù)組中索引 start_pc 處的指令中發(fā)生變化。
8.10.3.3 LocalVariableTable
在方法調(diào)用時(shí),通過(guò)該屬性來(lái)確定某個(gè)局部變量的值。
LocalVariableTable 屬性中保存了一個(gè) local_variable_table[] 數(shù)組。一個(gè)數(shù)組元素表示一個(gè)局部變量。
該數(shù)組元素的結(jié)構(gòu)為:
    {
        u2 start_pc;
        u2 length;
        u2 name_index;
        u2 descriptor_index;
        u2 index;
    }
    其中:
    start_pc 和 length:start_pc 必須是對(duì) code[] 中某一指令操作碼的有效索引;
                        start_pc + length 要么是對(duì) code[] 中某一指令操作碼的有效索引,
                                要么是剛超過(guò) code[] 數(shù)組末尾的首個(gè)索引值。
                        當(dāng)程序執(zhí)行到 code[] 數(shù)組的 [start_pc, start_pc+length] 范圍內(nèi)時(shí),
                        該局部變量是有效的(即該局部變量必定有值存在)。
    name_index:是對(duì)常量池表的一個(gè)有效索引,該索引指向的常量池項(xiàng)的類型為 CONSTANT_Utf8_info,
                表示該局部變量名。
    descriptor_index:是對(duì)常量池表的一個(gè)有效索引,該索引指向的常量池項(xiàng)的類型為 CONSTANT_Utf8_info,
                      表示該局部變量的字段描述符(即局部變量的類型)。
    index:表示在方法調(diào)用時(shí),該局部變量在棧幀的局部變量表中的索引。
            如果棧幀的局部變量表中,index 索引處的局部變量是 long 或 double 類型,則占用 index 和 index+1 兩個(gè)位置。
8.10.3.4 LocalVariableTypeTable
當(dāng)局部變量的類型中包含泛型(如 T 或 List<T> 類型的局部變量),或泛型的具體類型(如 List<String> 類型的局部變量)時(shí),
這種類型的局部變量不僅會(huì)出現(xiàn)在 LocalVariableTable 屬性中,還會(huì)出現(xiàn)在 LocalVariableTypeTable 屬性中。

LocalVariableTypeTable 屬性中保存了一個(gè) local_variable_type_table[] 數(shù)組。一個(gè)數(shù)組元素表示一個(gè)局部變量。
該數(shù)組元素的結(jié)構(gòu)為:
    {
        u2 start_pc;
        u2 length;
        u2 name_index;
        u2 signature_index;
        u2 index;
    }

與 LocalVariableTable 屬性中的 local_variable_table[] 數(shù)組元素的唯一區(qū)別在于:
    local_variable_table[] 數(shù)組元素中使用 descriptor_index 指定的字段描述符來(lái)表示局部變量的類型;
    local_variable_type_table[] 數(shù)組元素中使用 signature_index 指定的字段簽名來(lái)表示局部變量的類型;

注意:字段描述符 和 字段簽名 是存在區(qū)別的。

字段簽名參考 《Java 虛擬機(jī)規(guī)范 Java SE 8 版》 中第 4.7.9 節(jié)內(nèi)容(Signature 屬性)

8.10.3.5 StackMapTable
該屬性用在虛擬機(jī)的類型檢查驗(yàn)證階段。
一個(gè)方法只能有 0 個(gè)或 1 個(gè) StackMapTable 屬性。
StackMapTable 屬性中保存了一個(gè) stack_map_frame[] 數(shù)組,其中 stack_map_frame 表示棧映射幀。
棧映射幀 stack_map_frame 指定了 code[] 中某一指令對(duì)應(yīng)的局部變量和操作數(shù)棧的類型。
通過(guò) StackMapTable 屬性中保存的棧映射幀集合(stack_map_frame[]),可以提高 JVM 在類型檢查的驗(yàn)證階段的效率。
8.10.3.6 RuntimeVisibleTypeAnnotationsRuntimeInvisisbleTypeAnnotations

RuntimeVisibleTypeAnnotations 屬性中保存了運(yùn)行時(shí)可見(jiàn)的注解集合

RuntimeVisibleTypeAnnotations 屬性中保存了運(yùn)行時(shí)不可見(jiàn)的注解集合

8.10.3.7 棧幀

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.10.3.8 局部變量表(local variable 又稱本地變量表)

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

8.10.3.9 Code 屬性在 class 文件中的解析舉例(Slot 可復(fù)用)

參考 《字節(jié)碼執(zhí)行引擎》 中的 局部變量表

一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

注意:方法調(diào)用時(shí),棧幀中的局部變量表中的局部變量所占的內(nèi)存空間是可以復(fù)用的。

也就是說(shuō),LocalVariableTable 屬性中保存的局部變量在局部變量表中的索引 index 可能跟其他局部變量的索引相同。如下圖所示:
一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM),JVM,jvm,Java,Class字節(jié)碼,ASM

上圖中,
locals=2,即局部變量在局部變量表中總共占 2 slot 單位的內(nèi)存空間。
根據(jù) LocalVariableTable 屬性中的內(nèi)容可知,局部變量表中保存了 3 個(gè)局部變量,
其中兩個(gè)局部變量的索引是相同的(即局部變量 test 和 e 的索引相同,都為 1),
也就是說(shuō),局部變量 test 和 e 共用了 1 slot 單位的內(nèi)存空間。

9. ASM 開(kāi)發(fā)

ASM 是一個(gè) Java 字節(jié)碼操控框架。通過(guò) ASM 可以動(dòng)態(tài)生成類或者增強(qiáng)既有類的功能。

ASM 可以直接生成 class 文件,也可以在 class 文件被加載到 Java 虛擬機(jī)之前,修改 class 文件中的內(nèi)容,從而 動(dòng)態(tài)改變類行為。

class 文件中保存的二進(jìn)制數(shù)據(jù)足夠用來(lái)解析所有與 Java 類相關(guān)的信息:類名稱、繼承關(guān)系、成員變量、成員方法、以及方法體中的 Java 代碼。

簡(jiǎn)單的說(shuō),ASM 可以讀取并解析 class 文件的內(nèi)容,并提供接口對(duì) class 文件的內(nèi)容進(jìn)行訪問(wèn)和修改。

目前許多框架如 CGLib、Hibernate、Spring 都直接或間接地使用 ASM 操作字節(jié)碼。

使用 ASM 需要導(dǎo)入依賴包:asm-7.3.1.jarasm-util-7.3.1.jar

9.1 編程模型和核心 API

ASM 提供了兩種編程模型:

  1. Core API

    提供了基于事件形式的編程模型。
    該模型不需要一次性地將整個(gè)類的結(jié)構(gòu)讀取到內(nèi)存中。
    因此這種方式更快,需要的內(nèi)存更少。
    但這種編程方式難度較大。
    
  2. Tree API

    提供了基于樹(shù)形的編程模型。
    該模型需要一次性地將整個(gè)類的結(jié)構(gòu)讀取到內(nèi)存中。
    因此這種方式需要的內(nèi)存更多。
    但這種編程方式較為簡(jiǎn)單。
    

9.2 ClassVisitor 開(kāi)發(fā)

ClassVisitorCore API 編程模型中提供的接口,用于對(duì)字節(jié)碼進(jìn)行操作。

ClassVisitor 接口中的每個(gè)方法對(duì)應(yīng)了 class 文件中的每一項(xiàng)。

ASM 提供了三個(gè)基于 ClassVisitor 接口的實(shí)現(xiàn)類來(lái)完成 class 文件的生成和轉(zhuǎn)換。

  1. ClassReader:用于解析一個(gè)類的 class 文件。
  2. ClassAdapter:實(shí)現(xiàn)會(huì)變化的功能。
  3. ClassWriter:用來(lái)輸出變化后的字節(jié)碼。

ASM 給我們提供了 ASMifier 工具來(lái)幫助開(kāi)發(fā),可使用 ASMifier 工具生成 ASM 結(jié)構(gòu)來(lái)對(duì)比。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-817708.html

9.3 MethodVisitor 開(kāi)發(fā)

9.4 實(shí)現(xiàn)模擬 AOP 功能

到了這里,關(guān)于一、認(rèn)識(shí) JVM 規(guī)范(JVM 概述、字節(jié)碼指令集、Class文件解析、ASM)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • JVM-透徹理解字節(jié)碼以及指令

    JVM-透徹理解字節(jié)碼以及指令

    一、字節(jié)碼與指令概述 生成字節(jié)碼: 解釋: ? ? ? ? cafe babe -? 魔數(shù) ? ? ? ? 0000 0031 - 版本號(hào),前面大版本,后面小版本 ? ? ? ? 0022 - 常量池大小 二、JVM編譯基本原理 示例: 大白話: ? ? ? ? 符號(hào)解析: int x = 5?-? int 類型的字段 x值為5 以及作用域 大白話: ? ? ? ?

    2024年01月22日
    瀏覽(22)
  • 深入理解JVM虛擬機(jī)第二十七篇:詳解JVM當(dāng)中InvokeDynamic字節(jié)碼指令,Java是動(dòng)態(tài)類型語(yǔ)言么?

    深入理解JVM虛擬機(jī)第二十七篇:詳解JVM當(dāng)中InvokeDynamic字節(jié)碼指令,Java是動(dòng)態(tài)類型語(yǔ)言么?

    ????? 學(xué)習(xí)交流群: ??1:這是孫哥suns給大家的福利! ?? 2:我們免費(fèi)分享Netty、Dubbo、k8s、Mybatis、Spring...應(yīng)用和源碼級(jí)別的視頻資料 ????3:QQ群: 583783824 ? ???? ?工作微信: BigTreeJava 拉你進(jìn)微信群,免費(fèi)領(lǐng)取! ????4:本文章內(nèi)容出自上述:Spring應(yīng)用課程!????

    2024年02月04日
    瀏覽(21)
  • “深入解析JVM內(nèi)部機(jī)制:從字節(jié)碼到垃圾回收“

    標(biāo)題:深入解析JVM內(nèi)部機(jī)制:從字節(jié)碼到垃圾回收 摘要:JVM(Java虛擬機(jī))是Java程序的運(yùn)行環(huán)境,它負(fù)責(zé)將Java字節(jié)碼轉(zhuǎn)換為機(jī)器指令并執(zhí)行。本文將深入探討JVM的內(nèi)部機(jī)制,從字節(jié)碼的加載、解析和執(zhí)行到垃圾回收的原理和實(shí)現(xiàn)方式。 字節(jié)碼加載和解析 在Java程序運(yùn)行之前,

    2024年02月14日
    瀏覽(20)
  • JVM(字節(jié)碼文件詳解)

    JVM(字節(jié)碼文件詳解)

    類加載器 運(yùn)行時(shí)數(shù)據(jù)區(qū)域 執(zhí)行引擎(主要理解垃圾回收器,及時(shí)編譯器) 本地方法 在講解字節(jié)碼文件組成前,可以安裝使用“ jclasslib ”工具或idea中“ jclasslib ”插件進(jìn)行字節(jié)碼文件查看 jclasslib的Github地址: https://github.com/ingokegel/jclasslib

    2024年01月23日
    瀏覽(23)
  • 【JVM】字節(jié)碼文件的組成

    1. 魔數(shù)與Class文件版本 ?魔數(shù)是一個(gè)用于校驗(yàn)字節(jié)碼文件是否有效的標(biāo)識(shí),位于文件開(kāi)頭的前四個(gè)字節(jié),魔數(shù)之后是次版本號(hào)和主版本號(hào),共同構(gòu)成了字節(jié)碼文件的版本號(hào)。 2.常量池 常量池是字節(jié)碼文件中的一個(gè)結(jié)構(gòu),包含了該類的所有常量,如數(shù)字,字符串,符號(hào)常量等。

    2024年02月02日
    瀏覽(47)
  • JVM系列-2.字節(jié)碼文件詳解

    JVM系列-2.字節(jié)碼文件詳解

    ??作者簡(jiǎn)介:大家好,我是愛(ài)吃芝士的土豆倪,24屆校招生Java選手,很高興認(rèn)識(shí)大家 ??系列專欄:Spring原理、JUC原理、Kafka原理、分布式技術(shù)原理、數(shù)據(jù)庫(kù)技術(shù)、JVM原理 ??如果感覺(jué)博主的文章還不錯(cuò)的話,請(qǐng)??三連支持??一下博主哦 ??博主正在努力完成2023計(jì)劃中:源碼

    2024年01月22日
    瀏覽(44)
  • 【JVM】字節(jié)碼文件的組成部分

    【JVM】字節(jié)碼文件的組成部分

    ??個(gè)人主頁(yè): ?? 葉落閑庭 ??我的專欄:?? c語(yǔ)言 數(shù)據(jù)結(jié)構(gòu) javaEE 操作系統(tǒng) Redis 石可破也,而不可奪堅(jiān);丹可磨也,而不可奪赤。 操作數(shù)棧是臨時(shí)存放數(shù)據(jù)的地方 局部變量表是存放方法中的局部變量的位置 觀察如下代碼的字節(jié)碼文件 具體的java源代碼: 要想看到j(luò)ava的字

    2024年02月08日
    瀏覽(26)
  • JVM——類加載與字節(jié)碼技術(shù)—類文件結(jié)構(gòu)

    JVM——類加載與字節(jié)碼技術(shù)—類文件結(jié)構(gòu)

    ? 由源文件被編譯成字節(jié)碼文件,然后經(jīng)過(guò)類加載器進(jìn)行類加載,了解類加載的各個(gè)階段,了解有哪些類加載器,加載到虛擬機(jī)中執(zhí)行字節(jié)碼指令,執(zhí)行時(shí)使用解釋器進(jìn)行解釋執(zhí)行,解釋時(shí)對(duì)熱點(diǎn)代碼進(jìn)行運(yùn)行期的編譯處理。? ??根據(jù)下面規(guī)范,魔數(shù),兩個(gè)版本,常量池信息

    2024年02月11日
    瀏覽(18)
  • 什么時(shí)候會(huì)觸發(fā)FullGC?描述一下JVM加載class文件的原理機(jī)制?

    什么時(shí)候會(huì)觸發(fā) FullGC? 除直接調(diào)用 System.gc 外,觸發(fā) Full GC 執(zhí)行的情況有如下四種。 1. 舊生代空間不足 舊生代空間只有 在新生代對(duì)象轉(zhuǎn)入及創(chuàng)建為大對(duì)象、大數(shù)組時(shí)才會(huì)出現(xiàn)不足的現(xiàn)象,當(dāng)執(zhí)行 Full GC 后空間仍然不 足,則拋出如下錯(cuò)誤: java.lang.OutOfMemoryError: Java heap spac

    2024年02月20日
    瀏覽(24)
  • class文件中,常量池之后的相關(guān)數(shù)據(jù)解析!【class二進(jìn)制文件分析】

    class文件中,常量池之后的相關(guān)數(shù)據(jù)解析!【class二進(jìn)制文件分析】

    前言:前段時(shí)間讀《深入java虛擬機(jī)》介紹到class文件的時(shí)候,由于理論知識(shí)較多,人總感覺(jué)疲憊不堪,就泛泛閱讀了一下。在工作中使用起來(lái)知識(shí)點(diǎn)知道,但是總是需要查閱各種資料。今天有時(shí)間,繼續(xù)整理常量池后面的相關(guān)知識(shí)。 class文件中,我們可以通過(guò)背或記也好,或

    2024年02月07日
    瀏覽(27)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包