JVM是面試必面的一個知識點,也是高級程式員必備的一個技能,以下是JVM整體核心內容,包括類加載系統,運行時資料區內部結構,執行引擎,本地方法介面,

首先來學習類的加載器,虛擬機把描述類的資料從Class檔案加載到記憶體,并對資料進行校驗、轉換決議和初始化,最終形成可以被虛擬機直接使用的Java型別,這就是虛擬機的加載機制,
類加載器子系統如下圖所示:

-
類加載器子系統負責從檔案系統或者網路中加載Class檔案,class檔案再檔案開頭有特定的檔案標識,
-
ClassLoader只負責class檔案的加載,至于是否可以運行,則由ExecutionEngine決定,
-
記載的類資訊存放于一塊稱為方法區的記憶體空間,除了類的資訊外,方法區還會存放運行時常量池資訊,可能還包括字串字面量和數字常量,
一、類加載程序
類加載程序分為加載,鏈接(驗證、準備、決議),初始化三個程序:

加載:
-
通過一個類的全限定名獲取定義此類的二進制位元組流,
-
將這個位元組流所代表的靜態存盤結構轉化為方法區的運行時資料結構,
-
在記憶體中生成一個代表這個類的java.lang.Class物件,作為方法區這個類的各種資料的訪問入口,
驗證:
目的是為了確保Class檔案的位元組流中包含資訊符合當前虛擬機的要求,保證加載類的正確性,不會危害虛擬機自身安全,
主要包括四種驗證:檔案格式驗證,元資料驗證,位元組碼驗證,符符號參考驗證,
準備:
-
為類變數分配記憶體并設定類變數初始值,即零值,
-
這里不包含用final修飾的static,因為final在編譯的時候就會分配了,準備階段會顯示的初始化,
-
這里不會為實體變數分配初始化,類變數會分配在方法區中,而實體變數會隨著物件一起分配到Java堆中,
決議:
決議階段是虛擬機將常量池內的符號參考替換為直接參考的程序,
事實上,決議操作往往伴隨著JVM在執行完初始化之后再執行,
初始化:
-
初始化階段就是執行類構造器方法<Clint>()的程序,
-
此方法不需定義,是javac編譯器自動收集類中的所有類變數的賦值動作和靜態代碼塊中的陳述句合并而來,
-
構造器方法中指令按陳述句在源檔案中出現的順序執行,
-
<clint>不同于類的構造器
-
若該類具有父類,JVM會保證子類的<clint> 執行前,父類的已經執行完畢,
-
虛擬機必須保證一個類的<clint>方法在多執行緒中被同步加鎖,
二、類加載器
JVM支持兩種型別的類加載器,分別為引導類加載器(Bootstrap ClassLoader)和自定義類加載器(User-Defined ClassLoader)
從概念上來講,自定義類加載器一般指的是程式中由開發人員自定義的一類類加載器,但是Java虛擬機規范沒有這么定義,而是將所有派生于抽象類ClassLoader的類加載器都劃分為自定義類加載器
引導類加載器是C++語言寫的,而自定義類加載器是Java語言寫的,
絕大部分Java程式都會使用到以下3種系統提供的類加載器,
啟動類加載器(Bootstrap ClassLoader)
-
這個類加載使用c/c++語言撰寫,嵌套在JVM內部,
-
它用來加載Java的核心庫(JAVA_HOME/jre/lib/rt.jar,resources.jar或sun.boot.class.path路徑下的內容),用于提供JVM自身需要的類,
-
并不繼承自java.lang.ClassLoader,沒有父記載器,
-
加載擴展類和應用程式類加載器,并制定為他們的父類加載器,
-
出于安全考慮,Bootstrap啟動類加載器指加載包名為java、javax、sun等開頭的類,
擴展類記載器(Extension classLoader)
-
Java語言撰寫,由sun.misc.Launcher$ExtClassLoader實作,
-
派生于ClassLoader類
-
父類加載器為啟動類加載器,
-
從java.ext.dirs系統屬性所指定的目錄中加載類別庫,或從JDK的安裝目錄jre/lib/ext子目錄下加載類別庫,如果用戶創建的JAR放在此目錄下,也會自動由擴展類加載器加載,
應用程式類加載器(AppClassLoader)
-
Java語言撰寫,由sun.misc.Launcher$AppClassLoader實作,
-
派生于ClassLoader類
-
父類加載器為擴展類加載器,
-
它負責加載環境變數classpath或系統屬性,java.class.path指定路徑下的類別庫,
-
該類加載是程式中默認的類加載器,一般來說,java的應用類都是有它來完成加載,
-
通過ClassLoader#getSystemClassLoader()方法可以獲取到該類加載器,
三、雙親委派機制
Java虛擬機對class檔案采用的是按需加載的方式,也就是說當需要使用該類時才會將它的class檔案加載到記憶體生成class物件,而且加載某個類的class檔案時,java虛擬機采用的是雙親委派模式,即把請求交由給父類處理,它是一種任務委派模式,
作業原理:
-
1.如果一個類加載器收到類加載請求,它并不會自己先去加載,而是把這個請求委托給父類的記載器去執行;
-
2.如果父類加載器還存在其父類加載器,則進一步向上委托,依次遞回,請求最終將到達頂層的啟動類加載器,
-
3.如果父類加載器可以完成類加載任務,就成功回傳,倘若父類加載器無法完成此加載任務,子加載器才會嘗試自己去加載,這就是雙親委派模式,
優勢:
-
避免類重復加載,
-
保護程式安全,防止核心API被隨意篡改,
作者:茶底世界 出處:https://www.cnblogs.com/yuanqinnan/ 原始碼地址:https://github.com/yuanqinnan/
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/298237.html
標籤:Java
上一篇:JavaIO編程——檔案常用操作
下一篇:mysqli的基本使用
