---
category: Java
tag:
- JVM
---
# ç±»å è½½å¨è¯¦è§£
## å顾ä¸ä¸ç±»å è½½è¿ç¨
ç±»å è½½è¿ç¨ï¼**å è½½->è¿æ¥->åå§å**ãè¿æ¥è¿ç¨åå¯åä¸ºä¸æ¥ï¼**éªè¯->åå¤->è§£æ**ã

ä¸ä¸ªéæ°ç»ç±»çå è½½é¶æ®µï¼å è½½é¶æ®µè·åç±»çäºè¿å¶åèæµçå¨ä½ï¼æ¯å¯æ§æ§æå¼ºçé¶æ®µï¼è¿ä¸æ¥æä»¬å¯ä»¥å»èªå®ä¹ç±»å è½½å¨å»æ§å¶åèæµçè·åæ¹å¼ï¼éåä¸ä¸ªç±»å è½½å¨ç `loadClass()` æ¹æ³ï¼ãæ°ç»ç±»åä¸éè¿ç±»å è½½å¨å建ï¼å®ç± Java èææºç´æ¥å建ã
ææçç±»é½ç±ç±»å è½½å¨å è½½ï¼å è½½çä½ç¨å°±æ¯å° `.class`æä»¶å è½½å°å
åã
## ç±»å è½½å¨æ»ç»
JVM ä¸å
ç½®äºä¸ä¸ªéè¦ç ClassLoaderï¼é¤äº BootstrapClassLoader å
¶ä»ç±»å è½½å¨åç± Java å®ç°ä¸å
¨é¨ç»§æ¿èª`java.lang.ClassLoader`ï¼
1. **BootstrapClassLoader(å¯å¨ç±»å è½½å¨)** ï¼æé¡¶å±çå 载类ï¼ç± C++å®ç°ï¼è´è´£å è½½ `%JAVA_HOME%/lib`ç®å½ä¸ç jar å
åç±»æè
被 `-Xbootclasspath`åæ°æå®çè·¯å¾ä¸çææç±»ã
2. **ExtensionClassLoader(æ©å±ç±»å è½½å¨)** ï¼ä¸»è¦è´è´£å è½½ `%JRE_HOME%/lib/ext` ç®å½ä¸ç jar å
åç±»ï¼æè¢« `java.ext.dirs` ç³»ç»åéææå®çè·¯å¾ä¸ç jar å
ã
3. **AppClassLoader(åºç¨ç¨åºç±»å è½½å¨)** ï¼é¢åæä»¬ç¨æ·çå è½½å¨ï¼è´è´£å è½½å½ååºç¨ classpath ä¸çææ jar å
åç±»ã
## åäº²å§æ´¾æ¨¡å
### åäº²å§æ´¾æ¨¡åä»ç»
æ¯ä¸ä¸ªç±»é½æä¸ä¸ªå¯¹åºå®çç±»å è½½å¨ãç³»ç»ä¸ç ClassLoader å¨ååå·¥ä½çæ¶åä¼é»è®¤ä½¿ç¨ **åäº²å§æ´¾æ¨¡å** ãå³å¨ç±»å è½½çæ¶åï¼ç³»ç»ä¼é¦å
夿å½åç±»æ¯å¦è¢«å è½½è¿ãå·²ç»è¢«å è½½çç±»ä¼ç´æ¥è¿åï¼å¦åæä¼å°è¯å è½½ãå è½½çæ¶åï¼é¦å
ä¼æè¯¥è¯·æ±å§æ´¾ç»ç¶ç±»å è½½å¨ç `loadClass()` å¤çï¼å æ¤ææçè¯·æ±æç»é½åºè¯¥ä¼ éå°é¡¶å±çå¯å¨ç±»å è½½å¨ `BootstrapClassLoader` ä¸ãå½ç¶ç±»å è½½å¨æ æ³å¤çæ¶ï¼æç±èªå·±æ¥å¤çãå½ç¶ç±»å è½½å¨ä¸º null æ¶ï¼ä¼ä½¿ç¨å¯å¨ç±»å è½½å¨ `BootstrapClassLoader` ä½ä¸ºç¶ç±»å è½½å¨ã

æ¯ä¸ªç±»å è½½é½æä¸ä¸ªç¶ç±»å è½½å¨ï¼æä»¬éè¿ä¸é¢çç¨åºæ¥éªè¯ã
```java
public class ClassLoaderDemo {
public static void main(String[] args) {
System.out.println("ClassLodarDemo's ClassLoader is " + ClassLoaderDemo.class.getClassLoader());
System.out.println("The Parent of ClassLodarDemo's ClassLoader is " + ClassLoaderDemo.class.getClassLoader().getParent());
System.out.println("The GrandParent of ClassLodarDemo's ClassLoader is " + ClassLoaderDemo.class.getClassLoader().getParent().getParent());
}
}
```
Output
```
ClassLodarDemo's ClassLoader is sun.misc.Launcher$AppClassLoader@18b4aac2
The Parent of ClassLodarDemo's ClassLoader is sun.misc.Launcher$ExtClassLoader@1b6d3586
The GrandParent of ClassLodarDemo's ClassLoader is null
```
`AppClassLoader`çç¶ç±»å è½½å¨ä¸º`ExtClassLoader`ï¼
`ExtClassLoader`çç¶ç±»å è½½å¨ä¸º nullï¼**null å¹¶ä¸ä»£è¡¨`ExtClassLoader`没æç¶ç±»å è½½å¨ï¼èæ¯ `BootstrapClassLoader`** ã
å
¶å®è¿ä¸ªå亲翻è¯ç容æè®©å«äººè¯¯è§£ï¼æä»¬ä¸è¬çè§£çåäº²é½æ¯ç¶æ¯ï¼è¿éçå亲æ´å¤å°è¡¨è¾¾çæ¯âç¶æ¯è¿ä¸è¾âç人èå·²ï¼å¹¶ä¸æ¯è¯´ççæä¸ä¸ª Mother ClassLoader åä¸ä¸ª Father ClassLoader ãå¦å¤ï¼ç±»å è½½å¨ä¹é´çâç¶åâå
³ç³»ä¹ä¸æ¯éè¿ç»§æ¿æ¥ä½ç°çï¼æ¯ç±âä¼å
çº§âæ¥å³å®ã宿¹ API ææ¡£å¯¹è¿é¨åçæè¿°å¦ä¸:
> The Java platform uses a delegation model for loading classes. **The basic idea is that every class loader has a "parent" class loader.** When loading a class, a class loader first "delegates" the search for the class to its parent class loader before attempting to find the class itself.
### åäº²å§æ´¾æ¨¡åå®ç°æºç åæ
åäº²å§æ´¾æ¨¡åçå®ç°ä»£ç é常ç®åï¼é»è¾é常æ¸
æ°ï¼é½éä¸å¨ `java.lang.ClassLoader` ç `loadClass()` ä¸ï¼ç¸å
³ä»£ç å¦ä¸æç¤ºã
```java
private final ClassLoader parent;
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) {//ç¶å è½½å¨ä¸ä¸ºç©ºï¼è°ç¨ç¶å è½½å¨loadClass()æ¹æ³å¤ç
c = parent.loadClass(name, false);
} else {//ç¶å è½½å¨ä¸ºç©ºï¼ä½¿ç¨å¯å¨ç±»å è½½å¨ BootstrapClassLoader å è½½
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
//æåºå¼å¸¸è¯´æç¶ç±»å è½½å¨æ æ³å®æå 载请æ±
}
if (c == null) {
long t1 = System.nanoTime();
//èªå·±å°è¯å è½½
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
```
### åäº²å§æ´¾æ¨¡åç好å¤
åäº²å§æ´¾æ¨¡åä¿è¯äº Java ç¨åºç稳å®è¿è¡ï¼å¯ä»¥é¿å
ç±»çéå¤å è½½ï¼JVM åºåä¸åç±»çæ¹å¼ä¸ä»
ä»
æ ¹æ®ç±»åï¼ç¸åçç±»æä»¶è¢«ä¸åçç±»å è½½å¨å 载产ççæ¯ä¸¤ä¸ªä¸åçç±»ï¼ï¼ä¹ä¿è¯äº Java çæ ¸å¿ API ä¸è¢«ç¯¡æ¹ãå¦ææ²¡æä½¿ç¨åäº²å§æ´¾æ¨¡åï¼èæ¯æ¯ä¸ªç±»å è½½å¨å è½½èªå·±çè¯å°±ä¼åºç°ä¸äºé®é¢ï¼æ¯å¦æä»¬ç¼åä¸ä¸ªç§°ä¸º `java.lang.Object` ç±»çè¯ï¼é£ä¹ç¨åºè¿è¡çæ¶åï¼ç³»ç»å°±ä¼åºç°å¤ä¸ªä¸åç `Object` ç±»ã
### 妿æä»¬ä¸æ³ç¨åäº²å§æ´¾æ¨¡åæä¹åï¼
~~为äºé¿å
åäº²å§ææºå¶ï¼æä»¬å¯ä»¥èªå·±å®ä¹ä¸ä¸ªç±»å è½½å¨ï¼ç¶åéå `loadClass()` å³å¯ã~~
**ð ä¿®æ£ï¼åè§ï¼[issue871](https://github.com/Snailclimb/JavaGuide/issues/871) ï¼** ï¼èªå®ä¹å è½½å¨çè¯ï¼éè¦ç»§æ¿ `ClassLoader` ã妿æä»¬ä¸æ³æç ´åäº²å§æ´¾æ¨¡åï¼å°±éå `ClassLoader` ç±»ä¸ç `findClass()` æ¹æ³å³å¯ï¼æ æ³è¢«ç¶ç±»å è½½å¨å è½½çç±»æç»ä¼éè¿è¿ä¸ªæ¹æ³è¢«å è½½ã使¯ï¼å¦ææ³æç ´åäº²å§æ´¾æ¨¡ååéè¦éå `loadClass()` æ¹æ³
## èªå®ä¹ç±»å è½½å¨
é¤äº `BootstrapClassLoader` å
¶ä»ç±»å è½½å¨åç± Java å®ç°ä¸å
¨é¨ç»§æ¿èª`java.lang.ClassLoader`ã妿æä»¬è¦èªå®ä¹èªå·±çç±»å è½½å¨ï¼å¾ææ¾éè¦ç»§æ¿ `ClassLoader`ã
## æ¨èé
读
-