JVM类加载(2)—连接
2、連接
連接就是將已經加載到內存中的類的二進制數據合并到Java虛擬機的運行時環境中去,加載階段尚未完成,連接階段可能已經開始。連接階段包含驗證、準備、解析過程。
2.1、驗證
驗證.class文件正確性,驗證階段大致會完成下面4個階段的檢驗動作
(1)、文件格式驗證,這一階段主要驗證字節流是否符合Class文件的格式規范,并且能被當前版本的虛擬機處理。
(2)、元數據驗證,第二階段是對字節碼描述信息進行語義分析,以保證其描述的信息符合Java語言規范的要求,這個階段可能包含的驗證點如下:
- 這個類是否有父類(除java.lang.Object類之外,其他所有類都應該有父類)
- 這個類的父類是否繼承了不允許被繼承的類(被final關鍵字修飾的類)
- 如果這個類不是抽象類,是否實現了其父類或接口之中要求實現的所有方法
- 類中的變量、方法是否與父類產生沖突(如覆蓋了父類的final屬性,或者出現不符合規則的方法重載)等
第二階段主要目的是對類的元數據信息進行語義校驗,保證不存在不符合Java語言規范的元數據信息。
(3)、字節碼驗證,第三階段是整個驗證過程中最復雜的一個階段,主要目的是通過數據流和控制流分析,確定程序語義是合法的、符合邏輯的。在第二階段對元數據信息中的數據做完驗證后,這個階段將對類的方法體進行校驗分析,保證被校驗類的方法在運行時不會做出危害JVM安全的事件,例如:
- 保證任意時刻操作數棧的數據類型與指令代碼序列能配合工作,例如不會出現類似這樣的情況:在操作棧放置了一個int型的數據,使用時卻按照long類型加載入本地變量表中。
- 保證跳轉指令不會跳轉到方法體以為的字節碼指令上。
- 保證方法體中的類型轉換是有效的。等
(4)、符號引用驗證,最后一個階段的校驗發生在虛擬機將符號引用轉化為直接引用的時候,這個轉化動作將在連接的第三階段——解析階段中發生。符號引用驗證可以看做是對類自身以外(常量池中的各種符號引用)的信息進行匹配性校驗,通常需要校驗以下內容:
- 符號引用中是否能通過字符串描述的全限定名找到對應的類
- 在指定類中是否存在符合方法描述的字段描述符以及簡單名稱所描述的方法和字段
- 符號引用中的類、字段、方法的訪問性(private、default、protected、public)是否可被當前類訪問。等
2.2、準備
為類的靜態變量分配內存,并初始化默認值,就像下面的這行代碼,在準備階段JVM給int變量i分配內存空間,并將i初始化為int型的默認值,在準備階段時i=0。
private static int i = 1;2.3、解析
解析階段JVM會把類中的符號引用轉換為直接引用,如下代碼,Test類中的showA()方法中調用了類A的print()方法,這里a.print()就是符號引用,在解析階段會把a.print()體會為方法區中一個指向A類的print()方法在方法區中內存地址的指針,而這個指針就是直接引用
1 class A{ 2 class A { 3 public void print() { 4 System.out.println("this is a"); 5 } 6 } 7 8 public class Test { 9 public void showA(A a) { 10 a.print(); 11 } 12 }?
符號引用(Symbolic References):符號引用是以一組符號來描述所引用的目標,符號可以是任何形式的字面量,只要使用時能無歧義的定位到目標即可。符號引用于虛擬機實現的內存布局無關,引用的目標不一定已經加載到內存中。各種虛擬機實現的內存可以各不相同,但是它們所接受的符號引用必須是一致的,因為符號引用的字面量形式明確定義在Java虛擬機規范的Class文件格式中。
直接引用(Direct References):直接引用可以是指向目標地址的指針、相對偏移量或是一個能間接定位到目標的句柄。直接引用是和虛擬機實現的內存布局是相關的,同一個符號引用在不同的虛擬機中翻譯出來的直接引用一般是不同的,如果有了直接引用,那引用目標一定已經在內存中了。
轉載于:https://www.cnblogs.com/qiyexue/p/6822201.html
總結
以上是生活随笔為你收集整理的JVM类加载(2)—连接的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 将ListT集合用DataGridVie
- 下一篇: 如何突破你的“内在阻力”,让你渴望多年的