JVM 学习四:类加载之双亲委派机制与沙箱安全机制
1 雙親委派機制
Java 虛擬機對 Class 文件的加載采用的是按需加載的方式,也就是說:當(dāng)需要使用該類時才會將它的 Class 文件加載到內(nèi)存生成 Class 對象,而且加載某個類的 Class 文件時,Java 虛擬機采用的是雙親委派模式,即把請求將由父類處理,它是一種任務(wù)委派模式。
1.1 工作原理
舉例:
1.2 雙親委派機制優(yōu)勢
- 避免類的重復(fù)加載
- 保護程序安全,防止核心 API 被隨意篡改
- 自定義類:java.lang.String
- 自定義類:java.lang.GldwolfStart --> 這個類不會被允許加載,因為 java.lang 包下的類是由 Bootstrap ClassLoader 加載的,由于安全原因,不會被加載:java.lang.SecurityException: Prohibited package name: java.lang
2 沙箱安全機制
自定義 java.lang.String 類,但是在加載自定義的 String 類的時候會首先使用引導(dǎo)類加載器加載,而引導(dǎo)類加載器在加載的過程中會先加載 JDK 自帶的文件(rt.jar 包中的 java.lang.String.class),而自定義的 java.lang.String 類中有 main 方法,JDK 中的 String 類沒有 main 方法,所以會報錯說沒有 main 方法,就是因為加載的不是自定義的 String 類。這樣可以保證對 java 核心源代碼的保護,這就是沙箱安全機制。
3 其它
在 JVM 中表示兩個 Class 對象是否為同一個類存在兩個必要條件:
- 類的完整類名必須一致,包括包名
- 加載這個類的 ClassLoader(指 ClassLoader 實例對象)必須相同
換句話說,在 JVM 中,即使這兩個類對象(Class 對象)來源于同一個 Class 文件,被同一個虛擬機所加載,但是只要加載它們的 ClassLoader 實例對象不同,那么這兩個類對象也是不相等的 。
3.1 對類加載器的引用
JVM 必須知道一個類是由啟動類加載器加載的還是由用戶類加載器加載的,如果一個類是由用戶類加載器加載的,那么 JVM 會將這個類加載器的一個引用作為類信息的一部分保存在方法區(qū)中。當(dāng)解析一個類型到另一個類型的引用的時候,JVM 需要保證這兩個類的類加載器是相同的。
3.2 類的主動使用和被動使用
Java 程序?qū)︻惖氖褂梅绞椒譃?#xff1a;主動使用和被動使用
3.2.1 主動使用
主動使用又分為 7 種情況:
- 創(chuàng)建類的實例
- 訪問某個類或接口的靜態(tài)變量,或者對該靜態(tài)變量賦值
- 調(diào)用類的靜態(tài)方法
- 反射(比如:Class.forName("top.gldwolf.Test"))
- 初始化一個類的子類
- Java 虛擬機啟動時被標(biāo)明為啟動類的類
- JDK 7 開始提供的動態(tài)語言支持:
- java.lang.invoke.MethodHandle 實例的解析結(jié)果
- REF_getStatic、REF_putStatic、REF_invokeStatic 句柄對應(yīng)的類沒有初始化,則初始化
3.2.2 被動使用
除了以上 7 種情況,其他使用 Java 類的方式都被看作是對類的被動使用,都不會導(dǎo)致類的初始化。
初始化:
總結(jié)
以上是生活随笔為你收集整理的JVM 学习四:类加载之双亲委派机制与沙箱安全机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jmeter修改redis_jmeter
- 下一篇: 快速排序c语言实现,快速排序的C语言代码