国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

JVM加載class文件原理

2019-11-11 02:40:59
字體:
來源:轉載
供稿:網友

前言

學習java、Android也有差不多半年時間了,是時候記錄一下學習過程中的心得和經驗,這篇文章就是簡單描述一下JVM加載class文件的機制。

JVM組成

圖1 JVM組成

Classloader 類加載器,負責查找并裝載Class 文件到內存,最終形成可以被虛擬機直接使用的Java類型Class Area 方法區(qū),在類裝載器加載class文件到內存的過程中,虛擬機會提取其中的類型信息,并將這些信息存儲到方法區(qū)。方法區(qū)用于存儲已被虛擬機加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數據。Heap 堆,存儲Java程序創(chuàng)建的類實例。Stack 棧,每當啟動一個新線程時,Java虛擬機都會為它分配一個Java棧。Java棧以幀為單位保存線程的運行狀態(tài)。虛擬機只會直接對Java棧執(zhí)行兩種操作:以幀為單位的壓?;虺鰲?。當線程調用java方法時,虛擬機壓入一個新的棧幀到該線程的java棧中。當方法返回時,這個棧幀被從java棧中彈出并拋棄。一個棧幀包含一個java方法的調用狀態(tài),它存儲有局部變量表、操作棧、動態(tài)鏈接、方法出口等信息。PC Register PC寄存器(程序計數器):一個運行中的Java程序,每當啟動一個新線程時,都會為這個新線程創(chuàng)建一個自己的PC寄存器(程序計數器)。程序計數器的作用可以看做是當前線程所執(zhí)行的字節(jié)碼的行號指示器。字節(jié)碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成。如果線程正在執(zhí)行的是一個Java方法,這個計數器記錄的是正在執(zhí)行的虛擬機字節(jié)碼指令的地址;如果正在執(zhí)行的是Natvie方法,這個計數器值則為空(Undefined)。Native Method Stack 本地方法棧,本地方法棧與虛擬機棧所發(fā)揮的作用是非常相似的,其區(qū)別不過是虛擬機棧為虛擬機執(zhí)行Java方法(也就是字節(jié)碼)服務,而本地方法棧則是為虛擬機使用到的Native方法服務。任何本地方法接口都會使用某種本地方法棧。當線程調用Java方法時,虛擬機會創(chuàng)建一個新的棧幀并壓入Java棧。然而當它調用的是本地方法時,虛擬機會保持Java棧不變,不再在線程的Java棧中壓入新的幀,虛擬機只是簡單地動態(tài)鏈接并直接調用指定的本地方法。如果某個虛擬機實現的本地方法接口是使用C連接模型的話,那么它的本地方法棧就是C棧。execution engine 執(zhí)行引擎,負責執(zhí)行字節(jié)碼。方法的字節(jié)碼是由Java虛擬機的指令序列構成的。每一條指令包含一個單字節(jié)的操作碼,后面跟隨0個或多個操作數。執(zhí)行引擎執(zhí)行字節(jié)碼時,首先取得一個操作碼,如果操作碼有操作數,取得它的操作數。它執(zhí)行操作碼和跟隨的操作數規(guī)定的動作,然后再取得下一個操作碼。這個執(zhí)行字節(jié)碼的過程在線程完成前將一直持續(xù)。Native Method interface 本地方法接口,作用是融合不同的編程語言為Java 所用,它的初衷是融合C/C++ 程序,Java 誕生的時候是C/C++ 橫行的時候,要想立足,必須有一個聰明的、睿智的調用C/C++ 程序,于是就在內存中專門開辟了一塊區(qū)域處理標記為native 的代碼,它的具體做法是Native Method Stack 中登記native 方法,在Execution Engine 執(zhí)行時加載native libraies 。目前該方法使用的是越來越少了,除非是與硬件有關的應用,比如通過Java 程序驅動打印機,或者Java 系統(tǒng)管理生產設備,在企業(yè)級應用中已經比較少見,因為現在的異構領域間的通信很發(fā)達,比如可以使用Socket 通信,也可以使用Web Service 等等,不多做介紹。

Classloader體系結構

Java中的類加載器實質上也是類,功能是把類載入jvm中,值得注意的是jvm的類裝載器并不是一個,而是三個: 1. BootstrapLoader 啟動類裝載器 : 每個Java虛擬機實現都必須有一個啟動類裝載器。它只負責在系統(tǒng)類(核心Java API的class文件)的安裝路徑中查找要裝入的類。這個裝載器的實現由C++ 所撰寫而成,是JVM實現的一部分。 2. ExtClassLoader 擴展類裝載器:負責除核心Java API以外的其它class文件的裝載。例如、用于安裝或下載標準擴展的class文件,在類路徑中發(fā)現的類庫的class文件,用于應用程序運行的class文件等等。 3. AppClassLoader 用戶自定義類裝載器:負責除核心Java API以外的其它class文件的裝載。這里有一點需要注意:自定義類裝載器并非由應用程序員自己實現,它也是JVM

JVM加載class的過程

當我們使用命令來執(zhí)行某一個Java程序(比如Test.class)的時候:java Test (1) java.exe 會幫助我們找到 JRE ,接著找到位于 JRE 內部的 jvm.dll ,這才是真正的 Java 虛擬機器 , 最后加載動態(tài)庫,激活 Java 虛擬機器。 (2) 虛擬機器激活以后,會先做一些初始化的動作,比如說讀取系統(tǒng)參數等。一旦初始化動作完成之后,就會產生第一個類裝載器 ―― BootstrapLoader(啟動類裝載器 ) 。 (3) Bootstrap Loader 所做的初始工作中,除了一些基本的初始化動作之外,最重要的就是加載 Launcher.java 之中的 ExtClassLoader(擴展類裝載器) ,并設定其 Parent 為 null ,代表其父加載器為 BootstrapLoader 。 (4) 然后 Bootstrap Loader 再要求加載 Launcher.java 之中的 AppClassLoader(用戶自定義類裝載器 ) ,并設定其 Parent 為之前產生的 ExtClassLoader 實體。這兩個加載器都是以靜態(tài)類的形式存在的。這里要注意的是, LauncherExtClassLoader.class與LauncherAppClassLoader.class 都是由 Bootstrap Loader 所加載,所以 Parent 和由哪個類加載器加載沒有關系。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 如东县| 东莞市| 分宜县| 江山市| 建瓯市| 鄂托克旗| 阳信县| 雅江县| 龙南县| 松原市| 安仁县| 特克斯县| 天水市| 虹口区| 界首市| 新乡市| 宁乡县| 台州市| 陕西省| 泽普县| 潼南县| 六盘水市| 当雄县| 安远县| 禹州市| 台南市| 阿巴嘎旗| 漯河市| 衡山县| 于田县| 多伦县| 绥芬河市| 龙陵县| 朝阳区| 色达县| 即墨市| 兰溪市| 通道| 太和县| 香格里拉县| 凤冈县|