浅析Java内存模型--ClassLoader
在理解ClassLoader之前,我們先回顧下Java的一些相關知識。
基礎
1. Java的主要特性
- 平臺無關性
- 面向對象
- GC(Java的垃圾回收機制)
- 類庫
- 語言特性
- 異常處理
2. 為什么JVM直接將 源碼解析成機器碼去執行
- 準備工作:每次執行都需要各種檢查
- 兼容性:也可以將別的語言解析成字節碼
Compile Once,Run Anywhere如何實現
? java源碼首先被編譯成字節碼,再由不同平臺的JVM進行解析,Java語言在不同的平臺上運行時不需要進行重新編譯,Java虛擬機在執行字節碼的時候,把字節碼 轉換成具體平臺上的機器指令。
3. JVM如何加載.class文件
- Class Loader:依據特定格式,加載class文件到內存
- Execution Engine:對命令 進行 解析
- Native Interface:融合不同開發語言的原生庫為 Java所用
- Runtime Data Area:JVM內存空間結構模型
4. 反射
? Java反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意 一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱為 Java語言的反射機制。
5. 類從編譯到執行的過程
- 編譯器將Xxx.java源文件編譯為Xxx.class字節碼文件
- ClassLoader 將字節碼轉換為JVM中的Class<Xxx>對象
- JVM利用Class<Xxx>對象實例化為Xxx對象
談談ClassLoader
? ClassLoader 在 Java 中有著非常重要的作用,它主要工作在 Class 裝載的加載階段,其主要作用是從系統外部獲得 Class 二進制數據流。它是 Java 的核心組件,所有的 Class 都是由 ClassLoader 進行加載的,ClassLoader 負責通過將 Class 文件里的二進制數據流裝載進系統,然后交給 Java 虛擬機進行連接、初始化等操作。
1. ClassLoader的種類
- BootStrapClassLoader:C++ 編寫,加載核心庫 java.*
- ExcClassLoader:Java 編寫,加載擴展庫 javax.*
- AppClassLoader:Java 編寫,加載程序所在目錄
- 自定義 ClassLoader:Java 編寫,定制化加載
2. 自定義 ClassLoader 的實現
關鍵函數:
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的區別
類的裝載過程
5. loadClass和forName的區別
- Class.forName得到的class是已經初始化完成的
- Classloader.loadClass得到的class是還沒有鏈接的
6. 談談類加載器的雙親委派機制
不同類的加載方式和加載路徑不同,為了實現分工,各自實現各自的功能,使得邏輯更加的明確,才有這么多共存的ClassLoader,加載類會根據各自的區域各司其職,而雙親委派機制會使這些加載器相互協調,形成一個整體。
雙親委派機制的原理圖:
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) {// 如果未發現類,則拋出異常}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;} }為什么要使用雙親委派機制去加載類?
為了避免多份同樣字節碼的加載。(通過逐層檢查可以避免多份由各自加載的相同 class文件 )
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的浅析Java内存模型--ClassLoader的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 目标检测学习笔记--DSSD算法
- 下一篇: 剑指offer(Java实现) 平衡二叉