浅析Java内存模型--ClassLoader
在理解ClassLoader之前,我們先回顧下Java的一些相關(guān)知識。
基礎(chǔ)
1. Java的主要特性
- 平臺無關(guān)性
- 面向?qū)ο?/li>
- GC(Java的垃圾回收機(jī)制)
- 類庫
- 語言特性
- 異常處理
2. 為什么JVM直接將 源碼解析成機(jī)器碼去執(zhí)行
- 準(zhǔn)備工作:每次執(zhí)行都需要各種檢查
- 兼容性:也可以將別的語言解析成字節(jié)碼
Compile Once,Run Anywhere如何實(shí)現(xiàn)
? java源碼首先被編譯成字節(jié)碼,再由不同平臺的JVM進(jìn)行解析,Java語言在不同的平臺上運(yùn)行時(shí)不需要進(jìn)行重新編譯,Java虛擬機(jī)在執(zhí)行字節(jié)碼的時(shí)候,把字節(jié)碼 轉(zhuǎn)換成具體平臺上的機(jī)器指令。
3. JVM如何加載.class文件
- Class Loader:依據(jù)特定格式,加載class文件到內(nèi)存
- Execution Engine:對命令 進(jìn)行 解析
- Native Interface:融合不同開發(fā)語言的原生庫為 Java所用
- Runtime Data Area:JVM內(nèi)存空間結(jié)構(gòu)模型
4. 反射
? Java反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對于任意 一個(gè)對象,都能夠調(diào)用它的任意方法和屬性;這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為 Java語言的反射機(jī)制。
5. 類從編譯到執(zhí)行的過程
- 編譯器將Xxx.java源文件編譯為Xxx.class字節(jié)碼文件
- ClassLoader 將字節(jié)碼轉(zhuǎn)換為JVM中的Class<Xxx>對象
- JVM利用Class<Xxx>對象實(shí)例化為Xxx對象
談?wù)凜lassLoader
? ClassLoader 在 Java 中有著非常重要的作用,它主要工作在 Class 裝載的加載階段,其主要作用是從系統(tǒng)外部獲得 Class 二進(jìn)制數(shù)據(jù)流。它是 Java 的核心組件,所有的 Class 都是由 ClassLoader 進(jìn)行加載的,ClassLoader 負(fù)責(zé)通過將 Class 文件里的二進(jìn)制數(shù)據(jù)流裝載進(jìn)系統(tǒng),然后交給 Java 虛擬機(jī)進(jìn)行連接、初始化等操作。
1. ClassLoader的種類
- BootStrapClassLoader:C++ 編寫,加載核心庫 java.*
- ExcClassLoader:Java 編寫,加載擴(kuò)展庫 javax.*
- AppClassLoader:Java 編寫,加載程序所在目錄
- 自定義 ClassLoader:Java 編寫,定制化加載
2. 自定義 ClassLoader 的實(shí)現(xiàn)
關(guān)鍵函數(shù):
protected Class<?> findClass(String name) throws ClassNotFoundException {throw new ClassNotFoundException(name); }protected final Class<?> defineClass(byte[] b, int off, int len) throws ClassFormatError {return defineClass(null, b, off, len, null); }3. 類的加載方式
- 隱式加載:new
- 顯示加載:loadClass,forName等
4. loadClass和forName的區(qū)別
類的裝載過程
5. loadClass和forName的區(qū)別
- Class.forName得到的class是已經(jīng)初始化完成的
- Classloader.loadClass得到的class是還沒有鏈接的
6. 談?wù)勵(lì)惣虞d器的雙親委派機(jī)制
不同類的加載方式和加載路徑不同,為了實(shí)現(xiàn)分工,各自實(shí)現(xiàn)各自的功能,使得邏輯更加的明確,才有這么多共存的ClassLoader,加載類會根據(jù)各自的區(qū)域各司其職,而雙親委派機(jī)制會使這些加載器相互協(xié)調(diào),形成一個(gè)整體。
雙親委派機(jī)制的原理圖:
loadClass源碼解析:
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// 首先,檢測該類是否已被加載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) {// 如果未發(fā)現(xiàn)類,則拋出異常}if (c == null) {// 如果仍未找到,則委托findClass方法去尋找long t1 = System.nanoTime();// 自定義的findClass方法c = findClass(name);sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;} }為什么要使用雙親委派機(jī)制去加載類?
為了避免多份同樣字節(jié)碼的加載。(通過逐層檢查可以避免多份由各自加載的相同 class文件 )
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的浅析Java内存模型--ClassLoader的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 目标检测学习笔记--DSSD算法
- 下一篇: 剑指offer(Java实现) 平衡二叉