日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JVM从入门到精通(二):详解Class加载过程,双亲委派机制,编译执行与解释执行

發布時間:2024/2/28 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM从入门到精通(二):详解Class加载过程,双亲委派机制,编译执行与解释执行 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

復習:Class文件結構

Class Loading Linking Initializing:編譯 加載 初始化

這節課,我們講 class 是怎么從硬盤中加載到內存中,并且準備執行的。

package com.mashibing.jvm.c2_classloader;public class T004_ParentAndChild {public static void main(String[] args) {System.out.println(T004_ParentAndChild.class.getClassLoader());System.out.println(T004_ParentAndChild.class.getClassLoader().getClass().getClassLoader());System.out.println(T004_ParentAndChild.class.getClassLoader().getParent());System.out.println(T004_ParentAndChild.class.getClassLoader().getParent().getParent());//System.out.println(T004_ParentAndChild.class.getClassLoader().getParent().getParent().getParent());} }

輸出:

jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc null jdk.internal.loader.ClassLoaders$PlatformClassLoader@1e643faf null

“雙親”這個詞不是特別好。實際上是有一個從子到父的過程,也有一個從父到子的過程。
(我理解的這個過程類似于DNS域名解析)是類似于遞歸的調用。
ClassLoader的Load過程,就是模板方法的設計模式。

手動加載一個類

package com.mashibing.jvm.c2_classloader;public class T005_LoadClassByHand {public static void main(String[] args) throws ClassNotFoundException {Class clazz = T005_LoadClassByHand.class.getClassLoader().loadClass("com.mashibing.jvm.c2_classloader.T002_ClassLoaderLevel");System.out.println(clazz.getName());//利用類加載器加載資源,參考坦克圖片的加載//T005_LoadClassByHand.class.getClassLoader().getResourceAsStream("");} }


可以看一下LoadClass源碼:

protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.long t1 = System.nanoTime();c = findClass(name);// this is the defining class loader; record the statsPerfCounter.getParentDelegationTime().addTime(t1 - t0);PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}}

關于編譯器

默認模式是混合模式,就是混合使用解釋器加熱點代碼編譯。什么叫熱點代碼編譯?
多次被調用的方法,多次被調用的循環進行編譯,怎么檢測呢?就是用一個計數器,每個方法上都有一個方法,計數器循環有循環計數器。結果在發現某個方法一秒鐘執行了超過某個10萬次。我要對他進行編譯,拿大腿想一想我該怎么辦?直接編譯成本地代碼,再用的話直接用本地的。不用解釋器執行了。

這時候會有人問,為什么不直接都編譯成本地代碼呢,執行效率更高,因為Java解釋器現在效率已經非常高了,在一些簡單的代碼上它不屬于便器。第二點,如果你有一段代碼執行文件,特別特別多各種各樣的類庫,有時候好幾十個class,這是正常的。你上來二話不說先給編譯器讓他編譯,編譯的過程會長的嚇人,所以現在默認的模式是混合模式,但是完全可以用參數來指定到底是什么模式。


這個東西是可以驗證的,有一個小程序,可以通過指定不同的參數,看一下編譯模式、解釋模式、混合模式的執行速度上的差異。
差不多編譯模式和混合模式都在4秒左右,解釋模式耗時比較長。

package com.mashibing.jvm.c2_classloader;public class T009_WayToRun {public static void main(String[] args) {for(int i=0; i<10_0000; i++)m();long start = System.currentTimeMillis();for(int i=0; i<10_0000; i++) {m();}long end = System.currentTimeMillis();System.out.println(end - start);}public static void m() {for(long i=0; i<10_0000L; i++) {long j = i%3;}} }

總結

以上是生活随笔為你收集整理的JVM从入门到精通(二):详解Class加载过程,双亲委派机制,编译执行与解释执行的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。