摘要:用一張思維導圖盡可能囊括一下的類加載過程的全流程。本文參考自來自周志明深入理解虛擬機第版,拓展內(nèi)容建議讀者可以閱讀下這本書。
用一張思維導圖盡可能囊括一下JVM的類加載過程的全流程。
本文參考自來自周志明《深入理解Java虛擬機(第2版)》,拓展內(nèi)容建議讀者可以閱讀下這本書。
文字版如下:
加載 Loading 過程
通過類的全限定名來獲取定義此類的二進制字節(jié)流
非數(shù)組類的加載,由類加載器加載,可以是啟動類加載器,也可以是用戶自定義的類加載器
數(shù)組類的加載,不由類加載器創(chuàng)建,而是由JVM直接在內(nèi)部創(chuàng)建
組件類型(數(shù)組降一維后的類型)是引用類型,遞歸調(diào)用加載過程直到降到一維類型后通過類加載器加載,數(shù)組類型最終標識為此類加載器所加載,數(shù)組類可見性和組件類型保持一致
組件類型不是引用類型而是原始類型,則該數(shù)組類型的類加載器將標識為啟動類加載器,數(shù)組類型可見性為public
將這個字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運行時數(shù)據(jù)結(jié)構(gòu)
在內(nèi)存中(HotSpot為方法區(qū))生成一個代表了這個類的java.lang.Class對象,作為方法區(qū)這個類的各種數(shù)據(jù)的訪問入口
類加載器啟動類加載器 Bootstrap ClassLoader,加載
拓展類加載器 Extension ClassLoader,加載
應(yīng)用程序類加載器 Application ClassLoader,加載用戶類路徑上的ClassPath中的類
自定義類加載器 User ClassLoader
連接 Linking 驗證 Verification
文件格式驗證:字節(jié)流是否符合Class文件格式規(guī)范
是否以magic開頭
主次版本號是否在虛擬機處理范圍內(nèi)
常量池中的常量是否有不支持的類型
指向的常量索引值是否有指向不存在常量或不符合類型常量的情況
CONSTANT_Utf8_info的常量是否符合utf8編碼規(guī)范
Class文件各個部分及文件本身是否有被刪除或附加的其他信息
元數(shù)據(jù)驗證:字節(jié)碼描述的信息進行語義分析
是否有父類
父類是否繼承了不允許被繼承的類(final的)
如果不是抽象類是否實現(xiàn)了其父類或接口之中要求實現(xiàn)的類
類中字段、方法是否與父類產(chǎn)生矛盾
覆蓋了父類的final字段
不符合規(guī)范的方法重載?方法參數(shù)類型一致返回值類型不一致
字節(jié)碼驗證:通過數(shù)據(jù)流和控制流分析程序語義的合法性,即類的方法體的校驗分析
保證時刻操作數(shù)棧與指令代碼序列能配合工作
保證跳轉(zhuǎn)指令不會跳轉(zhuǎn)到方法體以外的字節(jié)碼指令上
保證方法體的類型轉(zhuǎn)換是有效的
符號引用驗證:類的常量池中各種符號引用的信息進行匹配性校驗
符號引用中通過字符串描述的全限定名是否能找到對應(yīng)類
指定類中是否存在符合方法的字段描述符以及簡單名稱所描述的方法和字段
符號引用中的類、字段和方法的訪問性是否可被當前類所訪問
連接 Linking 驗證 Verification
文件格式驗證:字節(jié)流是否符合Class文件格式規(guī)范
是否以magic開頭
主次版本號是否在虛擬機處理范圍內(nèi)
常量池中的常量是否有不支持的類型
指向的常量索引值是否有指向不存在常量或不符合類型常量的情況
CONSTANT_Utf8_info的常量是否符合utf8編碼規(guī)范
Class文件各個部分及文件本身是否有被刪除或附加的其他信息
元數(shù)據(jù)驗證:字節(jié)碼描述的信息進行語義分析
是否有父類
父類是否繼承了不允許被繼承的類(final的)
如果不是抽象類是否實現(xiàn)了其父類或接口之中要求實現(xiàn)的類
類中字段、方法是否與父類產(chǎn)生矛盾
覆蓋了父類的final字段
不符合規(guī)范的方法重載?方法參數(shù)類型一致返回值類型不一致
字節(jié)碼驗證:通過數(shù)據(jù)流和控制流分析程序語義的合法性,即類的方法體的校驗分析
保證時刻操作數(shù)棧與指令代碼序列能配合工作
保證跳轉(zhuǎn)指令不會跳轉(zhuǎn)到方法體以外的字節(jié)碼指令上
保證方法體的類型轉(zhuǎn)換是有效的
符號引用驗證:類的常量池中各種符號引用的信息進行匹配性校驗
符號引用中通過字符串描述的全限定名是否能找到對應(yīng)類
指定類中是否存在符合方法的字段描述符以及簡單名稱所描述的方法和字段
符號引用中的類、字段和方法的訪問性是否可被當前類所訪問
準備 Preparation類變量分配空間
類變量分配零值
類常量分配初始值:由類字段的ConstantValue屬性進行賦值
解析 Resolution
實際上就是把常量池中的符號引用替換為直接引用的過程
符號引用
在常量池中即非字面量的類型
CONSTANT_Class_info
CONSTANT_Fieldref_info
CONSTANT_Methodref_info
CONSTANT_InterfaceMethodref_info
…
特征
與虛擬機實現(xiàn)的內(nèi)存布局無關(guān)
引用的目標并不一定已經(jīng)加載到內(nèi)存中
由虛擬機Class文件格式規(guī)范,因此不同虛擬機能夠接受的符號引用格式是確定的
直接引用
表達形式
直接指向目標的虛擬機內(nèi)存中的指針
相對偏移量
能夠定位到目標的句柄
特征
與虛擬機的內(nèi)存布局直接相關(guān)
引用的目標必須已經(jīng)存在于內(nèi)存中
同一符號引用在不同虛擬機中的直接引用一般不同,由虛擬機自己制定格式
符號引用解析
類或接口的解析
對CONSTANT_Class_info符號引用的解析
對全限定名的解析
虛擬機加載類D中的類符號引用N為一個類或接口C的直接引用
C不是數(shù)組類型
虛擬機將N代表的全限定名傳遞給D的類加載器來加載C
C被成功加載后(可能是之前已經(jīng)加載過或者本次執(zhí)行了首次加載),虛擬機將D中的符號引用N替換為C的直接引用
符號引用驗證,如D是否具備對C的訪問權(quán)限
C是數(shù)組類型?
虛擬機將N代表的全限定名(如[Ljava.lang.Integer)傳遞給D的類加載器來加載C(詳見數(shù)組類加載流程)
D的類加載器先加載C的組件類型(如java.lang.Integer)
虛擬機在方法區(qū)生成一個代表了數(shù)組維度和組件類型的數(shù)組對象
C被成功加載后,虛擬機將D中的符號引用N替換為C的直接引用
符號引用驗證,如D是否具備對C的訪問權(quán)限
字段解析
對CONSTANT_Fieldref_info符號引用的解析
對class_index的解析
對nameAndType_index的解析
虛擬機在類D中加載字段符號引用N為字段F的直接引用
虛擬機在N中指定的類C里尋找字段描述符和N中指定的字段描述符一致的字段F
能找到,就將符號引用N替換為F的直接引用
符號引用驗證,如D是否具備對F的訪問權(quán)限
找不到,在類C實現(xiàn)的接口中按照繼承關(guān)系從下向上尋找字段描述符和N中指定的字段描述符一致的字段F
能找到就將符號引用N替換為F的直接引用
符號引用驗證,如D是否具備對F的訪問權(quán)限
找不到,在類C繼承的父類中按照繼承關(guān)系從下向上尋找字段描述符和N中指定的字段描述符一致的字段F
能找到就將符號引用N替換為F的直接引用
符號引用驗證,如D是否具備對F的訪問權(quán)限
找不到,拋出java.lang.NoSuchFieldError異常
類方法解析
對CONSTANT_Methodref_info符號引用的解析
對class_index的解析
對nameAndType_index的解析
虛擬機在類D中加載類方法符號引用N為方法M的直接引用
虛擬機在N中指定的類C里尋找方法描述符和N中指定的方法描述符一致的方法M
能找到
class_index指定的類不是接口,就將符號引用N替換為M的直接引用
class_index指定的類是接口,拋出java.lang.IncompatibleClassChangeError異常
符號引用驗證,如D是否具備對M的訪問權(quán)限
找不到,在類C繼承的父類中按照繼承關(guān)系從下向上尋找方法描述符和N中指定的方法描述符一致的方法M
能找到就將符號引用N替換為M的直接引用
符號引用驗證,如D是否具備對M的訪問權(quán)限
找不到,在類C實現(xiàn)的接口中按照繼承關(guān)系從下向上尋找方法描述符和N中指定的方法描述符一致的方法M
能找到,說明類C是抽象類,拋出java.lang.AbstractMethodError異常(為什么說明C是抽象類呢?C的方法在C中找不到,但是在C實現(xiàn)的接口中找到了,這意味著C實現(xiàn)了接口但是沒有實現(xiàn)接口的這個方法,因此C類只可能是抽象類。)
找不到,拋出java.lang.NoSuchMethodError異常
接口方法解析
對CONSTANT_InterfaceMethodref_info符號引用的解析
對class_index的解析
對nameAndType_index的解析
虛擬機在類D中加載接口方法符號引用N為方法M的直接引用
虛擬機在N中指定的接口C里尋找方法描述符和N中指定的方法描述符一致的方法M
能找到
class_index指定的類是C接口,就將符號引用N替換為M的直接引用
class_index指定的類C不是接口,拋出java.lang.IncompatibleClassChangeError異常
符號引用驗證,接口方法都是public的所以沒有訪問權(quán)限的問題
找不到,在接口C繼承的父接口中按照繼承關(guān)系從下向上尋找方法描述符和N中指定的方法描述符一致的方法M
能找到就將符號引用N替換為M的直接引用
找不到,拋出java.lang.NoSuchMethodError異常
初始化 Initialization 初始化就是執(zhí)行父類的
接口無靜態(tài)代碼塊但是可以用類變量賦值操作,因此也會生成
虛擬機會保證多線程環(huán)境下類的
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/76792.html
摘要:本文是作者自己對中線程的狀態(tài)線程間協(xié)作相關(guān)使用的理解與總結(jié),不對之處,望指出,共勉。當中的的數(shù)目而不是已占用的位置數(shù)大于集合番一文通版集合番一文通版垃圾回收機制講得很透徹,深入淺出。 一小時搞明白自定義注解 Annotation(注解)就是 Java 提供了一種元程序中的元素關(guān)聯(lián)任何信息和著任何元數(shù)據(jù)(metadata)的途徑和方法。Annotion(注解) 是一個接口,程序可以通過...
摘要:本文參考自來自周志明深入理解虛擬機第版,拓展內(nèi)容建議讀者可以閱讀下這本書。和構(gòu)造方法一一對應(yīng),是同一概念在兩個級別的含義收斂的操作自動保證執(zhí)行父類的執(zhí)行語句塊初始化類變量字符串加操作替換為或的操作 showImg(https://segmentfault.com/img/remote/1460000016240419?w=3876&h=3614); 本文參考自來自周志明《深入理解Jav...
摘要:用于列舉最近分析過的文件常用功能欄,從左到右依次是概覽類直方圖支配樹查詢線程視圖報告相關(guān)詳細功能。針對那些占用堆內(nèi)存超過整個堆內(nèi)存大小的組件做一系列的分析,例如保留集合潛在的內(nèi)存浪費問題等其他問題。 上一篇文章MAT入門到精通(一)介紹了MAT的使用場景和基本概念,這篇文章開始介紹MAT的基本功能,后面還有兩篇,一篇是MAT的高級功能,另一篇是MAT實戰(zhàn)案例分析。 三、歡迎頁 使用MA...
摘要:編譯器只需面向,生成能理解的代碼或字節(jié)碼文件。源文件經(jīng)編譯器,編譯成字節(jié)碼程序,通過將每一條指令翻譯成不同平臺機器碼,通過特定平臺運行。漲見識,字節(jié)碼執(zhí)行過程分析。解決辦法減少默認棧的容量來換取更多的線程支持。 前言 JVM是java的核心和基礎(chǔ),在java編譯器和os平臺之間的虛擬處理器。它是一種基于下層的操作系統(tǒng)和硬件平臺并利用軟件方法來實現(xiàn)的抽象的計算機,可以在上面執(zhí)行java的...
摘要:編譯器只需面向,生成能理解的代碼或字節(jié)碼文件。源文件經(jīng)編譯器,編譯成字節(jié)碼程序,通過將每一條指令翻譯成不同平臺機器碼,通過特定平臺運行。漲見識,字節(jié)碼執(zhí)行過程分析。解決辦法減少默認棧的容量來換取更多的線程支持。 前言 JVM是java的核心和基礎(chǔ),在java編譯器和os平臺之間的虛擬處理器。它是一種基于下層的操作系統(tǒng)和硬件平臺并利用軟件方法來實現(xiàn)的抽象的計算機,可以在上面執(zhí)行java的...
閱讀 1013·2021-11-25 09:43
閱讀 1675·2019-08-30 13:59
閱讀 1600·2019-08-30 11:22
閱讀 2130·2019-08-30 11:06
閱讀 1305·2019-08-28 17:51
閱讀 3732·2019-08-26 12:12
閱讀 785·2019-08-26 12:11
閱讀 453·2019-08-26 12:10