JVM載入class原理

2022-09-18 06:21:44 字數 2258 閱讀 6898

當j**a編譯器編譯好.class檔案之後,我們需要使用jvm來執行這個class檔案。那麼最開始的工作就是要把位元組碼從磁碟輸入到記憶體中,這個過程我們叫做【載入】。載入完成之後,我們就可以進行一系列的執行前準備工作了,比如: 為類靜態變數開闢空間,將常量池存放在方法區記憶體中並實現常量池位址解析,初始化類靜態變數等等。這篇文章我們要好好談談jvm是如何載入class檔案的?

1、jvm載入類的過程

使用者自定義類裝載器經常依賴其他類裝載器——至少依賴於虛擬機器啟動時建立的啟動類裝載器—來幫助它實現一些類裝載請求:.在版本1.2前,非啟動類裝載器 必須顯式地求助於其他類裝載器,類裝載器可以請求另乙個使用者自定義的類裝載器來裝載乙個類,這個請求是通過對被請求的使用者自定義類裝載器呼叫 loadclass()來實現的。除此以外,類裝載器也可以通過呼叫findsystemclass()來請求啟動類裝載器來裝載類,這是類 classloader中的乙個靜態方法。

在版本1.2中,類裝載器請求另乙個類裝載器來裝載型別的過程被形式化,稱為雙親委派模式 。

從版本1.2開始、除啟動類裝載器以外的每乙個類裝載器,都有乙個「雙親」類裝載器 ,在某個特定的類裝載器試圖以常用方式裝載型別以前,它會先預設地將這個任務「委派」給它的雙親——清求它的雙親來裝載這個型別。這個雙親再依次請求它自 己的雙親來裝載這個型別。這個委派的過程一直向上繼續,直到達到啟動類裝載器,通常啟動類裝載器是委派鏈中的最後乙個類裝載器。如果乙個類裝載器的雙親類 裝載器有能力來裝載這個型別。則這個類裝載器返回這個型別。否則,這個類裝載器試圖自己來裝載這個類。

當j**a虛擬機器開始執行時,在應用程式開始啟動以前,它至少建立乙個使用者自定義裝載器,也可能建立多個.所有這些裝載器被連線在乙個parent-child的委託鏈中,在這個鏈的頂端是啟動類裝載器。

例如:假設你寫了乙個應用程式,在虛擬機器上執行它.虛擬機器在啟動時例項化了兩個使用者自定義類裝載器:乙個"擴充套件類裝載器",乙個"類路徑類裝載器".這些類裝載器和啟動類裝載器一起聯入乙個parent-child委託鏈中,如下圖所示.

上圖所示類路徑類裝載器的parent是擴充套件類裝載器, 擴充套件類裝載器的parent是啟動類裝載器.在圖2中,類路徑類裝載器就被例項為系統類裝載器.假設你的程式例項化它的網路類裝載器,它就指明了系統類裝載器作為它的parent.

下面的例程說明了類裝載器的父子關係.

j**a**  

package test;   

import j**a.net.url;   

import j**a.net.urlclassloader;   

public class classloadertest    

classloader cl = null;   

if (obj != null && !(obj instanceof classloader))  else if (obj != null)    

count++;   

string parent = "";   

for (int i = 0; i 

if (cl != null)  else    

}   

public static void main(string args)    

}    

4、乙個經典的例項說明

我們看看下面的**:

j**a**  

package j**a.lang;  

public class string   

}  j**a.lang.nosuchmethoderror: main

exception in thread "main"

這是為什麼? 我們的string類不是明明有main方法嗎?

啟動類載入器bootstraploader只能載入j**a_home\jre\lib中的class類(即j2se api),問題是標準api中確實有乙個j**a.lang.string(注意,這個類和我們自定義的類是完全兩個類)。bootstraploader以為找到了這個類,毫不猶豫的載入了j2se api中的j**a.lang.string。

最後出現上面的載入錯誤(注意不是異常,是錯誤,jvm退出),因為api中的string類是沒有main方法的。

結論:我們當然可以自定義乙個和api完全一樣的類,但是由於雙親委託模型,使得我們不可能載入上我們自定義的這樣乙個類。所以j2se規範中希望我們自定義的包有自己唯一的特色(網路網域名稱)。還有一點,這種載入器原理使得jvm更加安全的執行程式,因為黑客很難隨意的替代掉api中的**了。

JVM載入class檔案的原理機制?

jvm中類的裝載是由類載入器 classloader 和它的子類來實現的,j a中的類載入器是乙個重要的j a執行時系統元件,它負責在執行時查詢和裝入類檔案中的類。由於j a的跨平台性,經過編譯的j a源程式並不是乙個可執行程式,而是乙個或多個類檔案。當j a程式需要使用某個類時,jvm會確保這個類...

jvm原理 簡單的程式載入分析

package com.bzu.csh 類載入器載入.class檔案 初始化static宣告,並不賦值 呼叫類 static宣告賦值由上到下 程式開始執行,首先執行main方法,執行main方法第一條語句,呼叫singleton類的靜態方法,這裡呼叫singleton類的靜態方法就是主動使用sing...

jvm 類的載入機制與原理

jvm j a virtual machine 可以被拆分為好幾個部分,最開始的類載入器,執行引擎,本地介面 執行時資料區域。本章節主要針對類的載入機制進行說明 目前基本都知道,類在被執行時,需要經過堆類的載入,鏈結 驗證 準備 解析 和初始化的階段以及後面的 階段。那麼類是怎麼被載入的呢?類載入器...