国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 詳解JVM類加載機(jī)制及類緩存問題的處理方法

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

2021-03-14 13:37linuxidc Java教程

這篇文章主要給大家介紹了關(guān)于JVM類加載機(jī)制及類緩存問題的處理方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。

前言

大家應(yīng)該都知道,當(dāng)一個Java項目啟動的時候,JVM會找到main方法,根據(jù)對象之間的調(diào)用來對class文件和所引用的jar包中的class文件進(jìn)行加載(其步驟分為加載、驗證、準(zhǔn)備、解析、初始化、使用和卸載),方法區(qū)中開辟內(nèi)存來存儲類的運(yùn)行時數(shù)據(jù)結(jié)構(gòu)(包括靜態(tài)變量、靜態(tài)方法、常量池、類結(jié)構(gòu)等),同時在堆中生成相應(yīng)的Class對象指向方法區(qū)中對應(yīng)的類運(yùn)行時數(shù)據(jù)結(jié)構(gòu)。

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

對應(yīng)關(guān)系如下:

BootstrapClassLoader  用于加載JVM運(yùn)行所需要的類:

?
1
2
3
4
5
6
7
8
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 用于加載擴(kuò)展類:  

?
1
2
3
4
../Java/Extensions:
../JAVA_HOME/jre/lib/ext:    ../Library/Java/Extensions:/Network/Library/Java/Extensions:
../System/Library/Java/Extensions:
../lib/java

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

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

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

整個加載過程圖示如下:

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

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

類加載源的源碼跟蹤如下(在此對源碼進(jìn)行了適當(dāng)?shù)暮喕?,讀者可以點入源碼進(jìn)行查看:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package java.lang.ClassLoader;
import ....
 protected Class<?> loadClass(String name, boolean resolve)
  throws ClassNotFoundException
 {
  synchronized (getClassLoadingLock(name)) {
   // First,在虛擬機(jī)內(nèi)存中查找是否已經(jīng)加載過此類...類緩存的主要問題所在!??!
   Class<?> c = findLoadedClass(name);
   if (c == null) {
    long t0 = System.nanoTime();
    try {
     if (parent != null) {
               //先讓上一層加載器進(jìn)行加載
      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) {
            //調(diào)用此類加載器所實現(xiàn)的findClass方法進(jìn)行加載
     c = findClass(name);
    }
   }
   if (resolve) {
    resolveClass(c);
   }
   return c;
  }
 }

在源碼中可以完全領(lǐng)略到雙親委派機(jī)制的過程,其中最重要的三句代碼已經(jīng)進(jìn)行了標(biāo)注:

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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會調(diào)用此方法
  */
 @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流讀取,轉(zhuǎn)化為字節(jié)數(shù)組
 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;
 }
}

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

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

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

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

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

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。

原文鏈接:http://www.linuxidc.com/Linux/2018-01/150034.htm

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美在线免费观看 | 中文字幕日韩欧美一区二区三区 | 日韩欧美一区二区三区 | 国产成人精品一区二区三区视频 | 日韩欧美一区二区三区免费观看 | 欲色视频 | 亚洲精品成人悠悠色影视 | 久久免费精品一区二区三区 | 免费一级片免费一级片 | 亚洲国产精品网站 | 99久久国产免费 | 亚洲va中文字幕 | 91精品久久久久久久久久入口 | 精品国产青草久久久久福利 | 韩日毛片| 日韩大片在线观看 | 日韩欧美一区二区三区免费观看 | 欧美国产在线观看 | 狠狠干2024 | 久久久av| 中国大陆高清aⅴ毛片 | 午夜免费电影 | 国产人妖一区二区 | 欧美精品一区二区三区在线 | 久久久一区二区三区 | 欧美日韩第一页 | av色综合 | 日韩欧美中文字幕一区二区三区 | 国产在线一区二区三区 | 五月宗合网 | 国产精品18久久久久vr手机版特色 | 九九导航 | 黄色片在线观看视频 | 午夜四虎 | 亚洲精彩视频 | 一区二区日韩 | 超碰91在线 | 北条麻妃在线一区二区 | 偷拍自拍第一页 | 99热这里有精品 | 91精品福利少妇午夜100集 |