文章插圖

文章插圖
JVM系列筆記目錄
虛擬機的基礎概念class文件結構class文件加載過程jvm內存模型JVM常用指令GC與調優Class文件加載過程
JVM加載Class文件主要分3個過程:Loading 、Linking、Initialzing
1.Loading
Loading的過程就是通過類加載器將.class文件加載到jvm內存中過程 。需要理解雙親委派機制、類加載器ClassLoader,加載過程如下 。
不同的類加載器加載范圍不一樣,以Java8中的為例 。
BootClassLoader 加載范圍sun.boot.class.pahtExtClassLoader 加載范圍java.ext.dirsAppClassLoader 加載范圍java.class.pathCustomClassLoader 可自定義加載范圍前三個加載器來自JDK的Launcher類,三個ClassLoader作為Launcher的內部類,感興趣可以查看下源碼 。
開發者也可以自定義的ClassLoader,自定義記載范圍 。
雙親委派機制
自底向上檢查該類是否已經加載,parent方向;自頂向下進行類的實際查找和加載,child方向 。類的加載遵循雙親委派機制,主要是出于安全的考慮 。雙親委派機制是如何實現的,下面源碼會解釋 。
ClassLoader源碼
ClassLoader源碼中比較重要的一個函數是loadClass(),執行過程是:findLoadedClass()->parrent.loadClass()->findClass(),第一步是自底向上查詢是否已經加載,第二步是自頂向下查找加載類 。這里就規定或是說實現了雙親委派機制 。詳細見ClassLoader的源碼 。
自定義ClassLoader
如何自定義ClassLoader?可以繼承ClassLoader類,重新自己的findClass(),在里面調用defineClass()來實現自定義加載特定范圍的類 。
如何打破雙親委派機制,哪種情形下打破過?
從上面的ClassLoader源碼中大概能看出是如何實現了雙親委派機制的,從這入手可以通過2種方式打破該機制:
super(parent)指定parent會打破該機制自定義ClassLoader重寫loadClass()也可以打破何時打破過?雙親委派機制并不是不能打破,某些特殊場景下也會選擇打破該機制 。
JDK 1.2之前,自定義ClassLoader必須重寫loadClass(),打破過 。線程ThreadContextClassLoader可以實現基礎類調用實現類代碼,通過thread.setContextClassLoader指定 。熱啟動熱部署,如tomcat都有自己模塊指定的classloader,可以加載同一類庫的不同版本 。Class執行方式
Class執行方式分為3種:解釋執行、編譯執行、混合執行,各有優缺點,可通過參數指定 。
1.解釋執行:使用bytecode intepreter 解釋器解釋執行,該模式啟動很快,執行稍慢,可通過-Xint參數指定該模式 。2.編譯執行:使用 Just in time Complier JIT編譯器編譯執行,該模式執行很快,編譯很慢,可通過-Xcomp參數指定該模式 。3.混合執行:默認的模式,解釋器+熱點代碼編譯,開始解釋執行,啟動較快,對熱點代碼進行實時監測和編譯成本地代碼執行,可通過-Xmixed參數指定該模式 。
熱點代碼監測:多次被調用的方法用方法計數器,多次被調用的循環用循環計數器,可通過參數-XX:CompileThreshold = 10000指定觸發JIT編譯的閾值 。2.Linking
Linking鏈接的過程分3個階段:Vertification、Preparation、Resolution 。
Vertification: 驗證Class文件是否符合JVM規定 。Preparation:給靜態成員變量賦默認值Resolution:將類、方法、屬性等符號引用解釋為直接引用;常量池中的各種符號引用解釋為指針、偏移量等內存地址的直接引用3. Initializing
調用初始化代碼clint,給靜態成員變量賦初始值 。
這里可以了解下必須初始化的5種情況:
new getstatic putstatic invokestatic指令,訪問final變量除外java.lang.reflect對類進行反射調用時初始化子類的時候,父類必須初始化虛擬機啟動時,被執行的主類必須初始化動態語言支持java.lang.invoke.MethodHandler解釋的結果為REF_getstatic REF_putstatic REF_invokestatic的方法句柄時,該類必須初始化 。4.總結思考
設計模式中單例模式的雙重檢查的實現,INSTANCE是否需要加valatile?
public class Mgr06 {// 是否需要加volatile?private static volatile Mgr06 INSTANCE;private Mgr06() {}public static Mgr06 getInstance() {if (INSTANCE == null) {//雙重檢查synchronized (Mgr06.class) {if(INSTANCE == null) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}// new 了對象,不為null,但未完成變量的初始化復制,對象處于半初始化狀態,其它線程有可能取到半初始化的對象 。INSTANCE = new Mgr06();}}}return INSTANCE;}}復制代碼- springmvc文件上傳大小限制 spring boot文件上傳大小限制
- 手機data文件怎么打開方式 data文件怎么打開
- 常見的視頻格式文件有哪些 視頻是什么格式的文件
- 電腦如何清理緩存垃圾 電腦如何清理緩存文件
- 迅雷鏈接文件格式 迅雷下載地址格式是什么
- 電腦文件夾加密碼怎么設置密碼 電腦文件夾加密碼怎么設置
- psd文件太大怎么縮小分辨率 psd文件太大怎么縮小 2020
- 手機怎么打開CAD文件 用手機怎么打開cad文件
- tar命令刪除壓縮包中文件 tar 壓縮后刪除文件
- 文件強行刪除工具 怎么能強制刪除文件夾
