亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

詳解JVM類加載機制及類緩存問題的處理方法

2024-07-13 10:15:54
字體:
來源:轉載
供稿:網友

前言

大家應該都知道,當一個Java項目啟動的時候,JVM會找到main方法,根據對象之間的調用來對class文件和所引用的jar包中的class文件進行加載(其步驟分為加載、驗證、準備、解析、初始化、使用和卸載),方法區中開辟內存來存儲類的運行時數據結構(包括靜態變量、靜態方法、常量池、類結構等),同時在堆中生成相應的Class對象指向方法區中對應的類運行時數據結構。

用最簡單的一句話來概括,類加載的過程就是JVM根據所需的class文件的路徑,通過IO流的方式來讀取class字節碼文件,并通過一系列解析初始化等步驟來注入到內存。 java中的類加載器有:BootstrapClassLoader(最上層)、ExtClassLoader、AppClassLoader、以及用戶自定義的ClassLoader(最下層)。JVM對于不同種類的jar包(或class文件),會有不同種類的類加載器進行加載。

對應關系如下:

BootstrapClassLoader  用于加載JVM運行所需要的類:

    JAVA_HOME/jre/lib/resources.jar:    JAVA_HOME/jre/lib/rt.jar:    JAVA_HOME/jre/lib/sunrsasign.jar:    JAVA_HOME/jre/lib/jsse.jar:    JAVA_HOME/jre/lib/jce.jar:    JAVA_HOME/jre/lib/charsets.jar:    JAVA_HOME/jre/lib/jfr.jar:    JAVA_HOME/jre/classes

  ExtClassLoader 用于加載擴展類:  

    ../Java/Extensions:    ../JAVA_HOME/jre/lib/ext:    ../Library/Java/Extensions:/Network/Library/Java/Extensions:    ../System/Library/Java/Extensions:    ../lib/java

  AppClassLoader 用于加載我們項目中ClassPath下所創建的類和jar包中引用的類。

整個類加載,是通過一種叫做雙親委派的機制來進行加載。

舉例來說,一個類被最下層的加載器(用戶自定義ClassLoader)進行加載,此加載器首先會調用上一層的加載器(AppClassLoader)進行加載,而AppClassLoader會繼續轉交給上層(ExtClassLoader)的加載器進行加載,直到BootstrapClassLoader。  如果BootstrapClassLoader所加載的類路徑找不到此類,那么才會交給下一層的加載器(ExtClassLoader)進行加載,如果找不到此類,繼續交給下一層(AppClassLoader)進行加載。以此類推,如果用戶自定義的ClassLoader也找不到此類,那么程序就會拋出一個ClassNotFoundError。

整個加載過程圖示如下:

jvm類加載機制,jvm的類加載機制,jvm緩存

(圖片引用自:https://www.cnblogs.com/xing901022/p/4574961.html)

類加載源的源碼跟蹤如下(在此對源碼進行了適當的簡化),讀者可以點入源碼進行查看:

package java.lang.ClassLoader;import .... protected Class<?> loadClass(String name, boolean resolve)  throws ClassNotFoundException {  synchronized (getClassLoadingLock(name)) {   // First,在虛擬機內存中查找是否已經加載過此類...類緩存的主要問題所在!!!    Class<?> 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) {            //調用此類加載器所實現的findClass方法進行加載     c = findClass(name);    }   }   if (resolve) {    resolveClass(c);   }   return c;  } }

在源碼中可以完全領略到雙親委派機制的過程,其中最重要的三句代碼已經進行了標注:

  •     findLoadedClass(在虛擬機內存中查找是否已經加載過此類...類緩存的主要問題所在?。。。?/li>
  •     parent.loadClass(先讓上一層加載器進行加載)
  •     findClass(調用此類加載器所實現的findClass方法進行加載)

  如果用戶需要自定義加載器,加載自己指定路徑的class文件,需要繼承ClassLoader,并實現findClass(String name)方法。舉例如下:

package com.linuxidc.utils;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;public class ServiceClassLoader extends ClassLoader{ private String classPath; public ServiceClassLoader(String classPath) {  this.classPath = classPath; } /**  * 重寫父類的findClass 方法。 父類的loadClass會調用此方法  */ @Override protected Class<?> findClass(String name) throws ClassNotFoundException {  Class<?> c = null;  byte[] classData = getClassData(name);  if (classData!=null) {   c = defineClass(name, classData, 0, classData.length);  }else {   throw new ClassNotFoundException();  }  return c; }    // 將class文件通過IO流讀取,轉化為字節數組 private byte[] getClassData(String name) {    String path = classPath + "/"+ name.replace('.', '/') + ".class";    InputStream iStream = null;  ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  try {   iStream = new FileInputStream(path);      byte[] buffer = new byte[1024];   int temp = 0;   while ((temp = iStream.read(buffer))!=-1) {    byteArrayOutputStream.write(buffer, 0, temp);   }   if (byteArrayOutputStream!=null) {    return byteArrayOutputStream.toByteArray();   }  } catch (Exception e) {   e.printStackTrace();  }finally {   try {    if (iStream!=null) {     iStream.close();    }   } catch (IOException e) {    e.printStackTrace();   }   try {    if (byteArrayOutputStream!=null) {     byteArrayOutputStream.close();    }   } catch (IOException e) {    e.printStackTrace();   }  }  return null; }}

對類加載器的使用代碼如下:

ServiceClassLoader serviceClassLoader = new ServiceClassLoader("c:/myclass");Czlass<?> c = ServiceClassLoader.loadClass("com.linuxidc.service.Myclass");

如果 用同一個 ServiceClassLoader 對象去加載同一個Class文件多次,每次加載后的Class對象為同一個! 然而如果new不同的自定義ClassLoader去加載同一個Class文件,則每次會返回不同的Class對象。

注意: 不能將所要加載的Class文件放到classpath目錄及其任何子目錄下,否則會被AppClassLoader優先加載 (這是由于類加載采用雙親委派機制,同時AppClassLoader可以加載所有在classpath下的class文件), 每次都是同一個AppClassLoader進行加載,因此會出現類緩存問題。

這樣就解決了通常在JVM類加載時,直接使用反射出現的類緩存的問題。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩高清有码在线| 一区二区国产精品视频| 青草青草久热精品视频在线观看| 92福利视频午夜1000合集在线观看| 欧美怡春院一区二区三区| 国产性猛交xxxx免费看久久| 国产精品入口免费视频一| 国产欧美一区二区白浆黑人| 欧美理论电影在线播放| 激情久久av一区av二区av三区| 国产精品美女久久久久久免费| 欧美亚洲国产视频| 91精品成人久久| 日韩美女福利视频| 亚洲色图国产精品| 欧美极品少妇与黑人| 26uuu另类亚洲欧美日本老年| 亚洲a∨日韩av高清在线观看| 中文字幕综合一区| 国产精品久久999| 亚洲国产精品电影| 北条麻妃一区二区在线观看| 欧美成人午夜剧场免费观看| 亚洲成人黄色在线观看| 57pao国产精品一区| 青草成人免费视频| 欧美成人小视频| 国产日韩在线观看av| 国产精品999| 97精品国产97久久久久久春色| 欧美又大又粗又长| 日韩av片永久免费网站| 国产精品www网站| 国产精品久久久久久av福利软件| 狠狠色噜噜狠狠狠狠97| 欧美成人在线免费视频| 欧美中文在线观看| 日韩精品一二三四区| 欧美麻豆久久久久久中文| 欧美大尺度电影在线观看| 日韩久久免费视频| 欧美成人午夜视频| 成人深夜直播免费观看| 成人网在线免费看| 9.1国产丝袜在线观看| 日韩精品中文字幕有码专区| 欧美在线观看网站| 亚洲天堂av网| 在线国产精品视频| 秋霞成人午夜鲁丝一区二区三区| 国产精品一区二区女厕厕| 久久亚洲精品小早川怜子66| 亚洲美女视频网站| 久久综合88中文色鬼| 国模精品系列视频| 国产精品成av人在线视午夜片| 美女啪啪无遮挡免费久久网站| 国产欧美在线观看| 欧美一级高清免费| 久久久国产精品x99av| 国产精品久久久久高潮| 精品中文字幕视频| 青青草国产精品一区二区| 日韩av在线电影网| 欧美性生交大片免网| 一区二区三区国产视频| 在线播放国产一区中文字幕剧情欧美| 欧美夜福利tv在线| 欧美色图在线视频| 欧美精品九九久久| 不卡毛片在线看| 色综合天天狠天天透天天伊人| 久久久久亚洲精品| 亚洲成成品网站| 亚洲精品福利在线观看| 日韩欧美国产黄色| 亚洲偷欧美偷国内偷| 97福利一区二区| 日韩精品视频三区| 国产suv精品一区二区| 国产人妖伪娘一区91| 国产精品91免费在线| 亚洲欧美色图片| 欧美激情国产日韩精品一区18| 国产香蕉一区二区三区在线视频| 亚洲色图激情小说| 日韩欧美亚洲综合| 久久久久久伊人| 亚洲精品日韩欧美| 久久久久久九九九| 久久久久久久香蕉网| 日韩中文字幕网址| 亚洲欧美国产日韩天堂区| 5278欧美一区二区三区| 国产精品羞羞答答| 亚洲a级在线观看| 亚洲自拍偷拍网址| 91干在线观看| 欧美激情视频免费观看| 午夜精品一区二区三区视频免费看| 国产美女主播一区| 国产一区二区动漫| 国产精品久久国产精品99gif| 亚洲欧美激情精品一区二区| 国产精品美女免费看| 伊人一区二区三区久久精品| 亚洲精品视频播放| 亚洲无亚洲人成网站77777| 久久久久久这里只有精品| 亚洲女成人图区| 精品视频在线播放免| 亚洲国产三级网| 亚洲高清在线观看| 亚洲最新中文字幕| 成人免费高清完整版在线观看| 亚洲欧美成人网| 午夜精品理论片| 国产精品爱啪在线线免费观看| 日韩在线观看免费网站| 国产精品视频地址| www.久久撸.com| 久久久久久久国产精品视频| 欧美成年人视频网站欧美| 成人中心免费视频| 久久精品视频va| 欧美日韩国产综合新一区| 成人免费福利视频| 欧美激情精品久久久久久大尺度| 欧美日本高清一区| 久久精品中文字幕| 欧美在线观看视频| xxxxx91麻豆| 色777狠狠综合秋免鲁丝| 亚洲va码欧洲m码| 久久精品视频导航| 国产精品女主播视频| 亚洲bt天天射| 亚洲乱码国产乱码精品精天堂| 亚洲aⅴ日韩av电影在线观看| 国产精品高潮呻吟久久av野狼| 在线成人激情黄色| 亚洲人成电影网站色www| 国产精品久久久久久亚洲影视| 91在线观看免费观看| 中文国产成人精品| 中文字幕日韩有码| 国产mv久久久| 日韩成人中文字幕在线观看| 国产精品成人国产乱一区| 色av吧综合网| 成人福利网站在线观看11| 欧美日韩国产精品一区二区不卡中文| 国产精品99久久久久久人| 一区二区福利视频| 成人妇女淫片aaaa视频| 91精品国产乱码久久久久久久久| 亚洲欧美另类国产| 韩日欧美一区二区| 久久精品久久精品亚洲人| 久久午夜a级毛片| 欧美日本高清视频| 国产日韩视频在线观看| 国产mv久久久| 欧美日韩激情网|