成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

竟然還有人沒搞懂 JVM 類加載器?一文徹底明白

云計算 虛擬化
在Java面試中,在考察完項目經驗、基礎技術后,我會根據候選人的特點進行知識深度的考察,如果候選人簡歷上有寫JVM(Java虛擬機)相關的東西,那么我常常會問一些JVM的問題。

[[280350]]

寫在前面

在Java面試中,在考察完項目經驗、基礎技術后,我會根據候選人的特點進行知識深度的考察,如果候選人簡歷上有寫JVM(Java虛擬機)相關的東西,那么我常常會問一些JVM的問題。JVM的類加載機制是一個很經典的知識點,圍繞這個知識點可以有下面這些難度不同的問題。

  1. 簡單講下JVM中的類加載過程
  2. JVM中的類加載和卸載的時機?
  3. 如何理解JVM中不同類加載器的概念和作用?
  4. 簡單講下JVM中的雙親委派模型?
  5. 什么情況下會破壞雙親委派模型?為什么?可否舉個例子?
  6. Tomcat中的類加載機制有了解嗎?為什么這么設計?
  7. 實際開發中有遇到哪些類加載器相關的問題?你又是如何解決的?
  8. JVM之上的弱類型語言例如Groovy是如何實現?簡單講下動態類加載機制?

在接下來的幾篇文章,我將跟讀者一起重新梳理一遍類加載器的相關知識,爭取能夠妥善解答上面列出的這些問題。

基本概念篇

類的加載和卸載

JVM是虛擬機的一種,它的指令集語言是字節碼,字節碼構成的文件是class文件。平常我們寫的Java文件,需要編譯為class文件才能交給JVM運行。可以這么說:C語言代碼——>二進制文件——>計算機硬件,就相當于Java代碼——>字節碼文件——>JVM。JVM將指定的class文件讀取到內存里,并運行該class文件里的Java程序的過程,就稱之為類的加載;反之,將某個class文件的運行時數據從JVM中移除的過程,就稱之為類的卸載。

class文件的運行時數據就是C++對象,也稱為kclass對象,這些運行時數據在JDK7之前是放在永久代(PermGen),JDK8之后則放在元空間(Metaspace)。

類的生命周期

Java類從被虛擬機加載開始,到卸載出內存為止,它的整個生命周期包括:加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)7個階段;其中驗證、準備和解析又統稱為連接(Linking)階段。

 

竟然還有人沒搞懂 JVM 類加載器?一文徹底明白

 

類的加載的時機

虛擬機規范并未嚴格規定類加載的時機,跟具體的JVM虛擬機有關。類加載的最佳時機是解析Java字節碼類文件中常量池符號的時候,Class.forName()、ClassLoader.loadClass()、反射API和JNI_FindClass都可以觸發類加載,Hot JVM自身啟動的時候也會觸發類加載。

通過JVM參數中加-verbose:class,可以在應用啟動的時候打印類加載的過程,如下圖所示:

 

竟然還有人沒搞懂 JVM 類加載器?一文徹底明白

 

  1. 初始化這個階段,JVM虛擬機給出了5種必須對類進行“初始化”的情況
  2. 使用new關鍵字實例化對象的時候、讀取或設置一個類的靜態字段的時候、調用一個類的靜態方法的時候;
  3. 使用java.lang.reflect包的方法對類進行反射調用的時候,如果類沒有進行過初始化,則要先觸發其初始化;
  4. 當初始化一個類的時候,如果發現其父類還沒有被初始化,則要先初始化其父類;
  5. 當虛擬機啟動時,用戶需要指定一個執行的主類(包含main方法的那個類),則虛擬機會優先初始化這個主類;
  6. 在JDK1.7以后,動態語言支持的時候,如果一個java.lang.invoke.MethodHandle實例最后的結果是要執行第1種情況的操作,則也要進行初始化。

類的卸載時機

類的卸載跟采用的垃圾收集算法有關,在CMS中有兩種方法卸載不必要的類,一種是等到元空間(Metaspace)滿了的時候觸發FGC,另一種是使用跟CMS并發收集算法類似的方式,不過對于元空間的閾值和觸發CMS并發收集的閾值是獨立的。更具體的可以參考之前的文章:CMS學習筆記。在這里,我們只需要記住,JVM中一個類的卸載要滿足下面這3個條件:

  1. 該類所有的實例對象都已被回收;
  2. 該類的類加載器對象已經被回收;
  3. 該類對應的java.lang.Class對象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法。

類加載器的作用

類的加載是需要類加載器完成的,但是類加載器在JVM中的作用可不止這些。在JVM中,一個類的唯一性是需要這個類本身和類加載一起才能確定的,每個類加載器都有一個獨立的命名空間。

不同的類加載器,即使是同一個類字節碼文件,最后再JVM里的類對象也不是同一個,下面的代碼展示了這個結論:

  1. package jvm; 
  2. import java.io.IOException; 
  3. import java.io.InputStream; 
  4. public class ClassLoaderTest { 
  5.  public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, 
  6.  InstantiationException { 
  7.  ClassLoader myLoader = new ClassLoader() { 
  8.  @Override 
  9.  public Class<?> loadClass(String name) throws ClassNotFoundException { 
  10.  String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class"
  11.  InputStream inputStream = getClass().getResourceAsStream(fileName); 
  12.  if (inputStream == null) { 
  13.  return super.loadClass(name); 
  14.  } 
  15.  try { 
  16.  byte[] b = new byte[inputStream.available()]; 
  17.  inputStream.read(b); 
  18.  return defineClass(name, b, 0, b.length); 
  19.  } catch (IOException e) { 
  20.  throw new ClassNotFoundException(); 
  21.  } 
  22.  } 
  23.  }; 
  24.  Object obj = myLoader.loadClass("jvm.ClassLoaderTest").newInstance(); 
  25.  System.out.println(obj.getClass()); 
  26.  System.out.println(obj instanceof jvm.ClassLoaderTest); 
  27.  ClassLoaderTest classLoaderTest = new ClassLoaderTest(); 
  28.  System.out.println(classLoaderTest.getClass()); 
  29.  System.out.println(classLoaderTest instanceof jvm.ClassLoaderTest); 
  30.  } 

上述代碼的運行結果是:

 

竟然還有人沒搞懂 JVM 類加載器?一文徹底明白

 

可以看出,代碼中使用自定義類加載器(myLoader)加載的jvm.ClassLoaderTest類和通過應用程序類加載器加載的類不是同一個類。綜上,類加載器在JVM中的作用有:

  1. 將類的字節碼文件從JVM外部加載到內存中
  2. 確定一個類的唯一性
  3. 提供隔離特性,為中間件開發者提供便利,例如Tomcat

 

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2020-12-07 06:19:50

監控前端用戶

2021-07-08 10:08:03

DvaJS前端Dva

2024-05-11 14:18:44

迭代器模式業務

2021-06-30 08:45:02

內存管理面試

2022-06-07 10:13:22

前端沙箱對象

2020-03-18 14:00:47

MySQL分區數據庫

2024-05-13 10:45:25

中介模式面向對象數量

2024-05-10 08:43:04

外觀模式接口系統

2024-05-09 09:09:19

組合模式對象

2019-11-06 17:30:57

cookiesessionWeb

2019-08-27 14:46:59

ElasticSearES數據庫

2022-04-11 10:56:43

線程安全

2023-05-29 08:45:45

Java注解數據形式

2024-05-17 10:08:59

享元模式分類方式

2024-08-08 14:57:32

2024-05-15 17:41:37

備忘錄模式多線程

2023-11-23 06:50:08

括號

2020-12-18 09:36:01

JSONP跨域面試官

2022-03-24 08:51:48

Redis互聯網NoSQL

2021-08-05 06:54:05

觀察者訂閱設計
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产午夜精品一区二区三区嫩草 | 成年人视频在线免费观看 | 日本一区二区三区四区 | 91av视频在线免费观看 | 四虎成人免费视频 | 亚洲精品国产第一综合99久久 | 欧美jizzhd精品欧美巨大免费 | av在线免费观看网址 | 国产成人一区二区三区精 | 在线观看视频亚洲 | 午夜一区二区三区 | 国产97久久 | 在线免费中文字幕 | 嫩草视频网 | 欧美黄 片免费观看 | 99久久精品视频免费 | 国产美女在线播放 | 欧美成人精品一区二区男人看 | 中国免费黄色片 | 日韩欧美国产一区二区三区 | 一区二区三区精品在线视频 | 国产精品久久久久久婷婷天堂 | 久久专区 | 天天操欧美| 亚洲精品一区中文字幕乱码 | 亚洲视频欧美视频 | 一区在线视频 | 99re在线视频| 91中文在线观看 | 国产精品99999999| 日韩精品一区二区三区中文在线 | 精品久久久久久亚洲综合网 | 中文字幕在线人 | av黄色片 | 九九九久久国产免费 | 一区二区三区中文字幕 | 婷婷久久综合 | 午夜影院在线观看免费 | 一区二区三区国产好 | 鲁一鲁资源影视 | 精品一区二区三区在线观看 |