---
sidebar: heading
---

## ä»ä¹æ¯JVMï¼
JVMï¼å
¨ç§°Java Virtual Machineï¼Javaèææºï¼ï¼æ¯éè¿å¨å®é
çè®¡ç®æºä¸ä»¿ç模æåç§è®¡ç®æºåè½æ¥å®ç°çãç±**ä¸å¥åèç æä»¤éãä¸ç»å¯åå¨ãä¸ä¸ªæ ãä¸ä¸ªåå¾åæ¶å åä¸ä¸ªå卿¹æ³åç**ç»æãJVMå±è½äºä¸æä½ç³»ç»å¹³å°ç¸å
³çä¿¡æ¯ï¼ä½¿å¾Javaç¨åºåªéè¦çæå¨Javaèææºä¸è¿è¡çç®æ 代ç ï¼åèç ï¼ï¼å°±å¯å¨å¤ç§å¹³å°ä¸ä¸å ä¿®æ¹çè¿è¡ï¼è¿ä¹æ¯Javaè½å¤â**䏿¬¡ç¼è¯ï¼å°å¤è¿è¡ç**âåå ã
## 讲ä¸ä¸JVMå
åç»æï¼
JVMå
åç»æå为5大åºåï¼**ç¨åºè®¡æ°å¨**ã**èææºæ **ã**æ¬å°æ¹æ³æ **ã**å **ã**æ¹æ³åº**ã

**ç¨åºè®¡æ°å¨**
线ç¨ç§æçï¼ä½ä¸ºå½å线ç¨çè¡å·æç¤ºå¨ï¼ç¨äºè®°å½å½åèææºæ£å¨æ§è¡ççº¿ç¨æä»¤å°åãç¨åºè®¡æ°å¨ä¸»è¦æä¸¤ä¸ªä½ç¨ï¼
1. å½åçº¿ç¨ææ§è¡çåèç çè¡å·æç¤ºå¨ï¼éè¿å®å®ç°**代ç çæµç¨æ§å¶**ï¼å¦ï¼é¡ºåºæ§è¡ãéæ©ã循ç¯ãå¼å¸¸å¤çã
2. å¨å¤çº¿ç¨çæ
åµä¸ï¼ç¨åºè®¡æ°å¨ç¨äº**è®°å½å½åçº¿ç¨æ§è¡çä½ç½®**ï¼å½çº¿ç¨è¢«åæ¢åæ¥çæ¶åè½å¤ç¥éå®ä¸æ¬¡æ§è¡çä½ç½®ã
ç¨åºè®¡æ°å¨æ¯å¯ä¸ä¸ä¸ªä¸ä¼åºç° `OutOfMemoryError` çå
ååºåï¼å®ççå½å¨æéç线ç¨çå建èå建ï¼éç线ç¨çç»æèæ»äº¡ã
**èææºæ **
Java èææºæ æ¯ç±ä¸ä¸ªä¸ªæ å¸§ç»æï¼èæ¯ä¸ªæ 帧ä¸é½æ¥æï¼**å±é¨åé表**ã**æä½æ°æ **ã**卿龿¥**ã**æ¹æ³åºå£ä¿¡æ¯**ãæ¯ä¸æ¬¡å½æ°è°ç¨é½ä¼æä¸ä¸ªå¯¹åºçæ 帧被åå
¥èææºæ ï¼æ¯ä¸ä¸ªå½æ°è°ç¨ç»æåï¼é½ä¼æä¸ä¸ªæ 帧被弹åºã
å±é¨åé表æ¯ç¨äºåæ¾æ¹æ³åæ°åæ¹æ³å
çå±é¨åéã
æ¯ä¸ªæ 帧é½å
å«ä¸ä¸ªæåè¿è¡æ¶å¸¸éæ± ä¸è¯¥æ æå±æ¹æ³ç符å·å¼ç¨ï¼å¨æ¹æ³è°ç¨è¿ç¨ä¸ï¼ä¼è¿è¡å¨æé¾æ¥ï¼å°è¿ä¸ªç¬¦å·å¼ç¨è½¬åä¸ºç´æ¥å¼ç¨ã
- é¨å符å·å¼ç¨å¨ç±»å è½½é¶æ®µçæ¶å就转åä¸ºç´æ¥å¼ç¨ï¼è¿ç§è½¬åå°±æ¯éæé¾æ¥
- é¨å符å·å¼ç¨å¨è¿è¡æé´è½¬åä¸ºç´æ¥å¼ç¨ï¼è¿ç§è½¬åå°±æ¯å¨æé¾æ¥
Java èææºæ 乿¯çº¿ç¨ç§æçï¼æ¯ä¸ªçº¿ç¨é½æåèªç Java èææºæ ï¼èä¸éç线ç¨çå建èå建ï¼éç线ç¨çæ»äº¡èæ»äº¡ãJava èææºæ ä¼åºç°ä¸¤ç§é误ï¼`StackOverFlowError` å `OutOfMemoryError`ã
å¯ä»¥éè¿` -Xss `åæ°æ¥æå®æ¯ä¸ªçº¿ç¨çèææºæ å
å大å°ï¼
```java
java -Xss2M
```
**æ¬å°æ¹æ³æ **
èææºæ ä¸ºèææºæ§è¡ `Java` æ¹æ³æå¡ï¼èæ¬å°æ¹æ³æ åä¸ºèææºä½¿ç¨å°ç `Native` æ¹æ³æå¡ã`Native` æ¹æ³ä¸è¬æ¯ç¨å
¶å®è¯è¨ï¼CãC++çï¼ç¼åçã
æ¬å°æ¹æ³è¢«æ§è¡çæ¶åï¼å¨æ¬å°æ¹æ³æ ä¹ä¼å建ä¸ä¸ªæ 帧ï¼ç¨äºåæ¾è¯¥æ¬å°æ¹æ³çå±é¨åé表ãæä½æ°æ ã卿龿¥ãåºå£ä¿¡æ¯ã
**å **
å ç¨äºåæ¾å¯¹è±¡å®ä¾ï¼æ¯å徿¶éå¨ç®¡çç主è¦åºåï¼å æ¤ä¹è¢«ç§°ä½`GC`å ãå å¯ä»¥ç»åä¸ºï¼æ°ç代ï¼`Eden`空é´ã`From Survivor`ã`To Survivor`空é´ï¼åè年代ã
éè¿ `-Xms`设å®ç¨åºå¯å¨æ¶å ç¨å
å大å°ï¼éè¿`-Xmx`设å®ç¨åºè¿è¡æé´æå¤§å¯å ç¨çå
å大å°ã妿ç¨åºè¿è¡éè¦å ç¨æ´å¤çå
åï¼è¶
åºäºè¿ä¸ªè®¾ç½®å¼ï¼å°±ä¼æåº`OutOfMemory`å¼å¸¸ã
```java
java -Xms1M -Xmx2M
```
1.æ¹æ³åº
æ¹æ³åºä¸ Java å 䏿 ·ï¼æ¯å个线ç¨å
±äº«çå
ååºåï¼å®ç¨äºåå¨å·²è¢«èææºå è½½ç类信æ¯ã常éãéæåéã峿¶ç¼è¯å¨ç¼è¯åç代ç çæ°æ®ã
å¯¹æ¹æ³åºè¿è¡åå¾åæ¶ç主è¦ç®æ æ¯**坹叏鿱 çåæ¶å对类çå¸è½½**ã
2.æ°¸ä¹
代
æ¹æ³åºæ¯ JVM çè§èï¼èæ°¸ä¹
代`PermGen`æ¯æ¹æ³åºçä¸ç§å®ç°æ¹å¼ï¼å¹¶ä¸åªæ `HotSpot` ææ°¸ä¹
代ã对äºå
¶ä»ç±»åçèææºï¼å¦`JRockit`æ²¡ææ°¸ä¹
代ãç±äºæ¹æ³åºä¸»è¦åå¨ç±»çç¸å
³ä¿¡æ¯ï¼æä»¥å¯¹äºå¨æçæç±»çåºæ¯æ¯è¾å®¹æåºç°æ°¸ä¹
代çå
åæº¢åºã
3.å
空é´
JDK 1.8 çæ¶åï¼`HotSpot`çæ°¸ä¹
代被彻åºç§»é¤äºï¼ä½¿ç¨å
ç©ºé´æ¿ä»£ãå
空é´çæ¬è´¨åæ°¸ä¹
代类似ï¼é½æ¯å¯¹JVMè§è䏿¹æ³åºçå®ç°ã两è
æå¤§çåºå«å¨äºï¼å
空é´å¹¶ä¸å¨èææºä¸ï¼èæ¯ä½¿ç¨ç´æ¥å
åã
为ä»ä¹è¦å°æ°¸ä¹
ä»£æ¿æ¢ä¸ºå
空é´å¢?
æ°¸ä¹
代å
ååéäº JVM å¯ç¨å
åï¼èå
空é´ä½¿ç¨çæ¯ç´æ¥å
åï¼åæ¬æºå¯ç¨å
åçéå¶ï¼è½ç¶å
空é´ä»æ§å¯è½æº¢åºï¼ä½æ¯ç¸æ¯æ°¸ä¹
代å
åæº¢åºçæ¦çæ´å°ã
**è¿è¡æ¶å¸¸éæ± **
è¿è¡æ¶å¸¸éæ± æ¯æ¹æ³åºçä¸é¨åï¼å¨ç±»å è½½ä¹åï¼ä¼å°ç¼è¯å¨çæçåç§åé¢éå符å·å¼å·æ¾å°è¿è¡æ¶å¸¸éæ± ãå¨è¿è¡æé´å¨æçæç常éï¼å¦ String ç±»ç intern()æ¹æ³ï¼ä¹ä¼è¢«æ¾å
¥è¿è¡æ¶å¸¸éæ± ã
**ç´æ¥å
å**
ç´æ¥å
å并䏿¯èææºè¿è¡æ¶æ°æ®åºçä¸é¨åï¼ä¹ä¸æ¯èææºè§èä¸å®ä¹çå
ååºåï¼ä½æ¯è¿é¨åå
åä¹è¢«é¢ç¹å°ä½¿ç¨ãèä¸ä¹å¯è½å¯¼è´ `OutOfMemoryError` é误åºç°ã
NIOçBufferæä¾äº`DirectBuffer`ï¼å¯ä»¥ç´æ¥è®¿é®ç³»ç»ç©çå
åï¼é¿å
å å
å
åå°å å¤å
åçæ°æ®æ·è´æä½ï¼æé«æçã`DirectBuffer`ç´æ¥åé
å¨ç©çå
åä¸ï¼å¹¶ä¸å ç¨å 空é´ï¼å
¶å¯ç³è¯·çæå¤§å
ååæä½ç³»ç»éå¶ï¼ä¸åæå¤§å å
åçéå¶ã
ç´æ¥å
åç读åæä½æ¯å å
åå¿«ï¼å¯ä»¥æåç¨åºI/Oæä½çæ§è½ãé常å¨I/Oéä¿¡è¿ç¨ä¸ï¼ä¼åå¨å å
å
åå°å å¤å
åçæ°æ®æ·è´æä½ï¼å¯¹äºéè¦é¢ç¹è¿è¡å
åé´æ°æ®æ·è´ä¸çå½å¨æè¾ççæåæ°æ®ï¼é½å»ºè®®åå¨å°ç´æ¥å
åã
## Java对象çå®ä½æ¹å¼
Java ç¨åºéè¿æ ä¸ç reference æ°æ®æ¥æä½å ä¸çå
·ä½å¯¹è±¡ã对象çè®¿é®æ¹å¼ç±èææºå®ç°èå®ï¼ç®å主æµçè®¿é®æ¹å¼æä½¿ç¨å¥æåç´æ¥æé两ç§ï¼
- å¦æä½¿ç¨å¥æçè¯ï¼é£ä¹ Java å ä¸å°ä¼åååºä¸åå
忥ä½ä¸ºå¥ææ± ï¼reference ä¸åå¨çå°±æ¯å¯¹è±¡ç奿å°åï¼è奿ä¸å
å«äºå¯¹è±¡å®ä¾æ°æ®ä¸ç±»åæ°æ®åèªçå
·ä½å°åä¿¡æ¯ã使ç¨å¥ææ¥è®¿é®çæå¤§å¥½å¤æ¯ reference ä¸åå¨çæ¯ç¨³å®ç奿å°åï¼å¨å¯¹è±¡è¢«ç§»å¨æ¶åªä¼æ¹å奿ä¸çå®ä¾æ°æ®æéï¼è reference æ¬èº«ä¸éè¦ä¿®æ¹ã
- ç´æ¥æéãreference ä¸åå¨çç´æ¥å°±æ¯å¯¹è±¡çå°åã对象å
å«å°å¯¹è±¡ç±»åæ°æ®çæéï¼éè¿è¿ä¸ªæéå¯ä»¥è®¿é®å¯¹è±¡ç±»åæ°æ®ã使ç¨ç´æ¥æéè®¿é®æ¹å¼æå¤§ç好å¤å°±æ¯è®¿é®å¯¹è±¡é度快ï¼å®èçäºä¸æ¬¡æéå®ä½çæ¶é´å¼éï¼èææºhotspotä¸»è¦æ¯ä½¿ç¨ç´æ¥æéæ¥è®¿é®å¯¹è±¡ã
## 说ä¸ä¸å æ çåºå«ï¼
1. å ç**ç©çå°ååé
**æ¯ä¸è¿ç»çï¼æ§è½è¾æ
¢ï¼æ çç©çå°ååé
æ¯è¿ç»çï¼æ§è½ç¸å¯¹è¾å¿«ã
2. å åæ¾çæ¯**对象çå®ä¾åæ°ç»**ï¼æ åæ¾çæ¯**å±é¨åéï¼æä½æ°æ ï¼è¿åç»æ**çã
3. å æ¯**线ç¨å
±äº«**çï¼æ æ¯**线ç¨ç§æ**çã
## ä»ä¹æ
åµä¸ä¼åçæ æº¢åºï¼
- å½çº¿ç¨è¯·æ±çæ æ·±åº¦è¶
è¿äºèææºå
许çæå¤§æ·±åº¦æ¶ï¼ä¼æåº`StackOverFlowError`å¼å¸¸ãè¿ç§æ
åµé常æ¯å ä¸ºæ¹æ³é彿²¡ç»æ¢æ¡ä»¶ã
- æ°å»ºçº¿ç¨çæ¶å没æè¶³å¤çå
åå»å建对åºçèææºæ ï¼èææºä¼æåº`OutOfMemoryError`å¼å¸¸ãæ¯å¦çº¿ç¨å¯å¨è¿å¤å°±ä¼åºç°è¿ç§æ
åµã
## ç±»æä»¶ç»æ
Class æä»¶ç»æå¦ä¸ï¼
```java
ClassFile {
u4 magic; //ç±»æä»¶çæ å¿
u2 minor_version;//å°çæ¬å·
u2 major_version;//å¤§çæ¬å·
u2 constant_pool_count;//叏鿱 çæ°é
cp_info constant_pool[constant_pool_count-1];//叏鿱
u2 access_flags;//ç±»çè®¿é®æ è®°
u2 this_class;//å½åç±»çç´¢å¼
u2 super_class;//ç¶ç±»
u2 interfaces_count;//æ¥å£
u2 interfaces[interfaces_count];//ä¸ä¸ªç±»å¯ä»¥å®ç°å¤ä¸ªæ¥å£
u2 fields_count;//åæ®µå±æ§
field_info fields[fields_count];//ä¸ä¸ªç±»ä¼å¯ä»¥æä¸ªå段
u2 methods_count;//æ¹æ³æ°é
method_info methods[methods_count];//ä¸ä¸ªç±»å¯ä»¥æä¸ªå¤ä¸ªæ¹æ³
u2 attributes_count;//æ¤ç±»ç屿§è¡¨ä¸ç屿§æ°
attribute_info attributes[attributes_count];//屿§è¡¨éå
}
```
主è¦åæ°å¦ä¸ï¼
**éæ°**ï¼`class`æä»¶æ å¿ã
**æä»¶çæ¬**ï¼é«çæ¬ç Java èææºå¯ä»¥æ§è¡ä½çæ¬ç¼è¯å¨çæçç±»æä»¶ï¼ä½æ¯ä½çæ¬ç Java èææºä¸è½æ§è¡é«çæ¬ç¼è¯å¨çæçç±»æä»¶ã
**叏鿱 **ï¼åæ¾åé¢éå符å·å¼ç¨ãåé¢éç±»ä¼¼äº Java ç常éï¼å¦å符串ï¼å£°æä¸º`final`ç常éå¼çã符å·å¼ç¨å
å«ä¸ç±»ï¼ç±»åæ¥å£çå
¨éå®åï¼æ¹æ³çåç§°åæè¿°ç¬¦ï¼å段çåç§°åæè¿°ç¬¦ã
**è®¿é®æ å¿**ï¼è¯å«ç±»æè
æ¥å£ç访é®ä¿¡æ¯ï¼æ¯å¦è¿ä¸ª`Class`æ¯ç±»è¿æ¯æ¥å£ï¼æ¯å¦ä¸º `public` æè
`abstract` ç±»åççã
**å½åç±»çç´¢å¼**ï¼ç±»ç´¢å¼ç¨äºç¡®å®è¿ä¸ªç±»çå
¨éå®åã
## ä»ä¹æ¯ç±»å è½½ï¼ç±»å è½½çè¿ç¨ï¼
ç±»çå è½½æçæ¯å°ç±»ç`class`æä»¶ä¸çäºè¿å¶æ°æ®è¯»å
¥å°å
åä¸ï¼å°å
¶æ¾å¨è¿è¡æ¶æ°æ®åºçæ¹æ³åºå
ï¼ç¶åå¨å åºå建ä¸ä¸ªæ¤ç±»ç对象ï¼éè¿è¿ä¸ªå¯¹è±¡å¯ä»¥è®¿é®å°æ¹æ³åºå¯¹åºç类信æ¯ã

**å è½½**
1. éè¿ç±»çå
¨éå®åè·åå®ä¹æ¤ç±»çäºè¿å¶åèæµ
2. å°åèæµæä»£è¡¨çéæåå¨ç»æè½¬æ¢ä¸ºæ¹æ³åºçè¿è¡æ¶æ°æ®ç»æ
3. å¨å
åä¸çæä¸ä¸ªä»£è¡¨è¯¥ç±»ç`Class`对象ï¼ä½ä¸ºæ¹æ³åºç±»ä¿¡æ¯ç访é®å
¥å£
**éªè¯**
ç¡®ä¿Classæä»¶çåèæµä¸å
å«çä¿¡æ¯ç¬¦åèææºè§èï¼ä¿è¯å¨è¿è¡åä¸ä¼å±å®³èææºèªèº«çå®å
¨ã主è¦å
æ¬åç§éªè¯ï¼**æä»¶æ ¼å¼éªè¯ï¼å
æ°æ®éªè¯ï¼åèç éªè¯ï¼ç¬¦å·å¼ç¨éªè¯**ã
**åå¤**
为类åéåé
å
å并设置类åéåå§å¼çé¶æ®µã
**è§£æ**
èææºå°å¸¸éæ± å
ç符å·å¼ç¨æ¿æ¢ä¸ºç´æ¥å¼ç¨çè¿ç¨ã符å·å¼ç¨ç¨äºæè¿°ç®æ ï¼ç´æ¥å¼ç¨ç´æ¥æåç®æ çå°åã
**åå§å**
å¼å§æ§è¡ç±»ä¸å®ä¹ç`Java`代ç ï¼åå§åé¶æ®µæ¯è°ç¨ç±»æé å¨çè¿ç¨ã
## ä»ä¹æ¯åäº²å§æ´¾æ¨¡åï¼
ä¸ä¸ªç±»å è½½å¨æ¶å°ä¸ä¸ªç±»çå è½½è¯·æ±æ¶ï¼å®é¦å
ä¸ä¼èªå·±å°è¯å»å è½½å®ï¼èæ¯æè¿ä¸ªè¯·æ±**å§æ´¾**ç»ç¶ç±»å è½½å¨å»å®æï¼è¿æ ·å±å±å§æ´¾ï¼å æ¤ææçå è½½è¯·æ±æç»é½ä¼ä¼ éå°é¡¶å±çå¯å¨ç±»å è½½å¨ä¸ï¼åªæå½ç¶ç±»å è½½å¨åé¦èªå·±æ æ³å®æè¿ä¸ªå è½½è¯·æ±æ¶ï¼åå è½½å¨æä¼å°è¯èªå·±å»å è½½ã

åäº²å§æ´¾æ¨¡åçå
·ä½å®ç°ä»£ç å¨ `java.lang.ClassLoader`ä¸ï¼æ¤ç±»ç `loadClass()` æ¹æ³è¿è¡è¿ç¨å¦ä¸ï¼å
æ£æ¥ç±»æ¯å¦å·²ç»å è½½è¿ï¼å¦ææ²¡æå让ç¶ç±»å è½½å¨å»å è½½ãå½ç¶ç±»å è½½å¨å è½½å¤±è´¥æ¶æåº `ClassNotFoundException`ï¼æ¤æ¶å°è¯èªå·±å»å è½½ãæºç å¦ä¸ï¼
```java
public abstract class ClassLoader {
// The parent class loader for delegation
private final ClassLoader parent;
public Class> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class> c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
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) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
protected Class> findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
}
```
## 为ä»ä¹éè¦åäº²å§æ´¾æ¨¡åï¼
åäº²å§æ´¾æ¨¡åç好å¤ï¼å¯ä»¥é²æ¢å
åä¸åºç°å¤ä»½åæ ·çåèç ãå¦ææ²¡æåäº²å§æ´¾æ¨¡åèæ¯ç±å个类å è½½å¨èªè¡å è½½çè¯ï¼å¦æç¨æ·ç¼åäºä¸ä¸ª`java.lang.Object`çåå类并æ¾å¨`ClassPath`ä¸ï¼å¤ä¸ªç±»å è½½å¨é½å»å è½½è¿ä¸ªç±»å°å
åä¸ï¼ç³»ç»ä¸å°ä¼åºç°å¤ä¸ªä¸åç`Object`ç±»ï¼é£ä¹ç±»ä¹é´çæ¯è¾ç»æåç±»çå¯ä¸æ§å°æ æ³ä¿è¯ã
## ä»ä¹æ¯ç±»å è½½å¨ï¼ç±»å è½½å¨æåªäº?
- å®ç°éè¿ç±»çå
¨éå®åè·å该类çäºè¿å¶åèæµç代ç åå«åç±»å è½½å¨ã
ä¸»è¦æä¸ä¸åç§ç±»å è½½å¨:
- **å¯å¨ç±»å è½½å¨**ï¼ç¨æ¥å è½½ Java æ ¸å¿ç±»åºï¼æ æ³è¢« Java ç¨åºç´æ¥å¼ç¨ã
- **æ©å±ç±»å è½½å¨**ï¼å®ç¨æ¥å è½½ Java çæ©å±åºãJava èææºçå®ç°ä¼æä¾ä¸ä¸ªæ©å±åºç®å½ã该类å è½½å¨å¨æ¤ç®å½é颿¥æ¾å¹¶å è½½ Java ç±»ã
- **ç³»ç»ç±»å è½½å¨**ï¼å®æ ¹æ®åºç¨çç±»è·¯å¾æ¥å è½½ Java ç±»ãå¯éè¿`ClassLoader.getSystemClassLoader()`è·åå®ã
- **èªå®ä¹ç±»å è½½å¨**ï¼éè¿ç»§æ¿`java.lang.ClassLoader`ç±»çæ¹å¼å®ç°ã
## ç±»çå®ä¾å顺åºï¼
1. ç¶ç±»ä¸ç`static`代ç åï¼å½åç±»ç`static`代ç å
2. ç¶ç±»çæ®é代ç å
3. ç¶ç±»çæé 彿°
4. å½åç±»æ®é代ç å
5. å½åç±»çæé 彿°
## å¦ä½å¤æä¸ä¸ªå¯¹è±¡æ¯å¦åæ´»ï¼
对å åå¾åæ¶åçç¬¬ä¸æ¥å°±æ¯è¦å¤æé£äºå¯¹è±¡å·²ç»æ»äº¡ï¼å³ä¸å被任ä½éå¾å¼ç¨ç对象ï¼ãå¤æå¯¹è±¡æ¯å¦åæ´»æä¸¤ç§æ¹æ³ï¼å¼ç¨è®¡æ°æ³åå¯è¾¾æ§åæã
**å¼ç¨è®¡æ°æ³**
ç»å¯¹è±¡ä¸æ·»å ä¸ä¸ªå¼ç¨è®¡æ°å¨ï¼æ¯å½æä¸ä¸ªå°æ¹å¼ç¨å®ï¼è®¡æ°å¨å°±å 1ï¼å½å¼ç¨å¤±æï¼è®¡æ°å¨å°±å 1ï¼ä»»ä½æ¶å计æ°å¨ä¸º 0 ç对象就æ¯ä¸å¯è½å被使ç¨çã
è¿ç§æ¹æ³å¾é¾è§£å³å¯¹è±¡ä¹é´ç¸äºå¾ªç¯å¼ç¨çé®é¢ãæ¯å¦ä¸é¢ç代ç ï¼`obj1` å `obj2` äºç¸å¼ç¨ï¼è¿ç§æ
åµä¸ï¼å¼ç¨è®¡æ°å¨çå¼é½æ¯1ï¼ä¸ä¼è¢«åå¾åæ¶ã
```java
public class ReferenceCount {
Object instance = null;
public static void main(String[] args) {
ReferenceCount obj1 = new ReferenceCount();
ReferenceCount obj2 = new ReferenceCount();
obj1.instance = obj2;
obj2.instance = obj1;
obj1 = null;
obj2 = null;
}
}
```
**å¯è¾¾æ§åæ**
éè¿`GC Root`对象为起ç¹ï¼ä»è¿äºèç¹åä¸æç´¢ï¼æç´¢æèµ°è¿çè·¯å¾å«å¼ç¨é¾ï¼å½ä¸ä¸ªå¯¹è±¡å°`GC Root`没æä»»ä½çå¼ç¨é¾ç¸è¿æ¶ï¼è¯´æè¿ä¸ªå¯¹è±¡æ¯ä¸å¯ç¨çã

## å¯ä½ä¸ºGC Rootsç对象æåªäºï¼
1. èææºæ ä¸å¼ç¨ç对象
2. æ¬å°æ¹æ³æ ä¸Nativeæ¹æ³å¼ç¨ç对象
3. æ¹æ³åºä¸ç±»éæå±æ§å¼ç¨ç对象
4. æ¹æ³åºä¸å¸¸éå¼ç¨ç对象
## ä»ä¹æ
åµä¸ç±»ä¼è¢«å¸è½½ï¼
éè¦åæ¶æ»¡è¶³ä»¥ä¸ 3 个æ¡ä»¶ç±»æå¯è½ä¼è¢«å¸è½½ ï¼
- 该类ææçå®ä¾é½å·²ç»è¢«åæ¶ã
- å 载该类çç±»å è½½å¨å·²ç»è¢«åæ¶ã
- 该类对åºç `java.lang.Class` 对象没æå¨ä»»ä½å°æ¹è¢«å¼ç¨ï¼æ æ³å¨ä»»ä½å°æ¹éè¿åå°è®¿é®è¯¥ç±»çæ¹æ³ã
èææºå¯ä»¥å¯¹æ»¡è¶³ä¸è¿° 3 个æ¡ä»¶çç±»è¿è¡åæ¶ï¼ä½ä¸ä¸å®ä¼è¿è¡åæ¶ã
## 强å¼ç¨ã软å¼ç¨ãå¼±å¼ç¨ãèå¼ç¨æ¯ä»ä¹ï¼æä»ä¹åºå«ï¼
**强å¼ç¨**ï¼å¨ç¨åºä¸æ®éåå¨çå¼ç¨èµå¼ï¼ç±»ä¼¼`Object obj = new Object()`è¿ç§å¼ç¨å
³ç³»ãåªè¦å¼ºå¼ç¨å
³ç³»è¿åå¨ï¼å徿¶éå¨å°±æ°¸è¿ä¸ä¼åæ¶æè¢«å¼ç¨ç对象ã
**软å¼ç¨**ï¼å¦æå
å空é´è¶³å¤ï¼åå¾åæ¶å¨å°±ä¸ä¼åæ¶å®ï¼å¦æå
å空é´ä¸è¶³äºï¼å°±ä¼åæ¶è¿äºå¯¹è±¡çå
åã
```java
//软å¼ç¨
SoftReference softRef = new SoftReference(str);
```
**å¼±å¼ç¨**ï¼å¨è¿è¡åå¾åæ¶æ¶ï¼ä¸ç®¡å½åå
å空é´è¶³å¤ä¸å¦ï¼é½ä¼åæ¶åªå
·æå¼±å¼ç¨ç对象ã
```java
//å¼±å¼ç¨
WeakReference weakRef = new WeakReference(str);
```
**èå¼ç¨**ï¼èå¼ç¨å¹¶ä¸ä¼å³å®å¯¹è±¡ççå½å¨æã妿ä¸ä¸ªå¯¹è±¡ä»
ææèå¼ç¨ï¼é£ä¹å®å°±å没æä»»ä½å¼ç¨ä¸æ ·ï¼å¨ä»»ä½æ¶åé½å¯è½è¢«åå¾åæ¶ã**èå¼ç¨ä¸»è¦æ¯ä¸ºäºè½å¨å¯¹è±¡è¢«æ¶éå¨åæ¶æ¶æ¶å°ä¸ä¸ªç³»ç»éç¥**ã
## GCæ¯ä»ä¹ï¼ä¸ºä»ä¹è¦GCï¼
GCï¼`Garbage Collection`ï¼ï¼åå¾åæ¶ï¼æ¯Javaä¸C++ç主è¦åºå«ä¹ä¸ãä½ä¸ºJavaå¼åè
ï¼ä¸è¬ä¸éè¦ä¸é¨ç¼åå
ååæ¶åå徿¸
ç代ç ãè¿æ¯å 为å¨Javaèææºä¸ï¼åå¨èªå¨å
å管çåå徿¸
çæºå¶ã对JVMä¸çå
åè¿è¡æ è®°ï¼å¹¶ç¡®å®åªäºå
åéè¦åæ¶ï¼æ ¹æ®ä¸å®çåæ¶çç¥ï¼èªå¨çåæ¶å
åï¼ä¿è¯JVMä¸çå
å空é´ï¼é²æ¢åºç°å
åæ³é²å溢åºé®é¢ã
## Minor GC å Full GCçåºå«ï¼
- **Minor GC**ï¼åæ¶æ°ç代ï¼å 为æ°çä»£å¯¹è±¡åæ´»æ¶é´å¾çï¼å æ¤ `Minor GC`ä¼é¢ç¹æ§è¡ï¼æ§è¡çé度ä¸è¬ä¹ä¼æ¯è¾å¿«ã
- **Full GC**ï¼åæ¶è年代忰ç代ï¼è年代çå¯¹è±¡åæ´»æ¶é´é¿ï¼å æ¤ `Full GC` å¾å°æ§è¡ï¼æ§è¡éåº¦ä¼æ¯ `Minor GC` æ
¢å¾å¤ã
## å
åçåé
çç¥ï¼
**对象ä¼å
å¨ Eden åé
**
大夿°æ
åµä¸ï¼å¯¹è±¡å¨æ°ç代 `Eden` ä¸åé
ï¼å½ `Eden` 空é´ä¸å¤æ¶ï¼è§¦å `Minor GC`ã
**å¤§å¯¹è±¡ç´æ¥è¿å
¥è年代**
å¤§å¯¹è±¡æ¯æéè¦è¿ç»å
å空é´çå¯¹è±¡ï¼æå
¸åç大对象æé¿å符串å大æ°ç»ãå¯ä»¥è®¾ç½®JVMåæ° `-XX:PretenureSizeThreshold`ï¼å¤§äºæ¤å¼çå¯¹è±¡ç´æ¥å¨è年代åé
ã
**é¿æåæ´»ç对象è¿å
¥è年代**
éè¿åæ° `-XX:MaxTenuringThreshold` å¯ä»¥è®¾ç½®å¯¹è±¡è¿å
¥è年代çå¹´é¾éå¼ã对象å¨`Survivor`åºæ¯ç»è¿ä¸æ¬¡ `Minor GC`ï¼å¹´é¾å°±å¢å 1 å²ï¼å½å®çå¹´é¾å¢å å°ä¸å®ç¨åº¦ï¼å°±ä¼è¢«æåå°è年代ä¸ã
**å¨æå¯¹è±¡å¹´é¾å¤å®**
å¹¶é对象çå¹´é¾å¿
é¡»è¾¾å° `MaxTenuringThreshold` æè½æåè年代ï¼å¦æå¨ `Survivor` ä¸ç¸å年龿æå¯¹è±¡å¤§å°çæ»åå¤§äº `Survivor` 空é´çä¸åï¼åå¹´é¾å¤§äºæçäºè¯¥å¹´é¾ç对象å¯ä»¥ç´æ¥è¿å
¥èå¹´ä»£ï¼æ éè¾¾å° `MaxTenuringThreshold` å¹´é¾éå¼ã
**空é´åé
æ
ä¿**
å¨åç `Minor GC` ä¹åï¼èææºå
æ£æ¥è年代æå¤§å¯ç¨çè¿ç»ç©ºé´æ¯å¦å¤§äºæ°ç代ææå¯¹è±¡æ»ç©ºé´ï¼å¦ææ¡ä»¶æç«çè¯ï¼é£ä¹ `Minor GC` æ¯å®å
¨çã妿䏿ç«çè¯èææºä¼æ¥ç `HandlePromotionFailure` ç弿¯å¦å
许æ
ä¿å¤±è´¥ã妿å
许ï¼é£ä¹å°±ä¼ç»§ç»æ£æ¥è年代æå¤§å¯ç¨çè¿ç»ç©ºé´æ¯å¦å¤§äºå次æåå°è年代对象çå¹³å大å°ï¼å¦æå¤§äºï¼å°å°è¯çè¿è¡ä¸æ¬¡ `Minor GC`ï¼å¦æå°äºï¼æè
`HandlePromotionFailure` çå¼ä¸ºä¸å
许æ
ä¿å¤±è´¥ï¼é£ä¹å°±è¦è¿è¡ä¸æ¬¡ `Full GC`ã
## Full GC çè§¦åæ¡ä»¶ï¼
å¯¹äº Minor GCï¼å
¶è§¦åæ¡ä»¶æ¯è¾ç®åï¼å½ Eden ç©ºé´æ»¡æ¶ï¼å°±å°è§¦å䏿¬¡ Minor GCãè Full GC è§¦åæ¡ä»¶ç¸å¯¹å¤æï¼æä»¥ä¸æ
åµä¼åç full GCï¼
**è°ç¨ System.gc()**
åªæ¯å»ºè®®èææºæ§è¡ Full GCï¼ä½æ¯èææºä¸ä¸å®çæ£å»æ§è¡ãä¸å»ºè®®ä½¿ç¨è¿ç§æ¹å¼ï¼èæ¯è®©èææºç®¡çå
åã
**è年代空é´ä¸è¶³**
è年代空é´ä¸è¶³ç常è§åºæ¯ä¸ºåææè®²çå¤§å¯¹è±¡ç´æ¥è¿å
¥è年代ãé¿æåæ´»ç对象è¿å
¥è年代çã为äºé¿å
以ä¸åå å¼èµ·ç Full GCï¼åºå½å°½éä¸è¦å建è¿å¤§çå¯¹è±¡ä»¥åæ°ç»ã注æç¼ç è§èé¿å
å
åæ³é²ã餿¤ä¹å¤ï¼å¯ä»¥éè¿ `-Xmn` åæ°è°å¤§æ°ç代ç大å°ï¼è®©å¯¹è±¡å°½é卿°çä»£è¢«åæ¶æï¼ä¸è¿å
¥è年代ãè¿å¯ä»¥éè¿ `-XX:MaxTenuringThreshold` è°å¤§å¯¹è±¡è¿å
¥è年代çå¹´é¾ï¼è®©å¯¹è±¡å¨æ°ç代å¤åæ´»ä¸æ®µæ¶é´ã
**空é´åé
æ
ä¿å¤±è´¥**
使ç¨å¤å¶ç®æ³ç Minor GC éè¦è年代çå
å空é´ä½æ
ä¿ï¼å¦ææ
ä¿å¤±è´¥ä¼æ§è¡ä¸æ¬¡ Full GCã
**JDK 1.7 å以åçæ°¸ä¹
代空é´ä¸è¶³**
å¨ JDK 1.7 å以åï¼HotSpot èææºä¸çæ¹æ³åºæ¯ç¨æ°¸ä¹
代å®ç°çï¼æ°¸ä¹
代ä¸åæ¾ç为ä¸äº Class çä¿¡æ¯ã常éãéæåéçæ°æ®ãå½ç³»ç»ä¸è¦å è½½çç±»ãåå°çç±»åè°ç¨çæ¹æ³è¾å¤æ¶ï¼æ°¸ä¹
代å¯è½ä¼è¢«å 满ï¼å¨æªé
置为éç¨ CMS GC çæ
åµä¸ä¹ä¼æ§è¡ Full GCã妿ç»è¿ Full GC ä»ç¶åæ¶ä¸äºï¼é£ä¹èææºä¼æåº `java.lang.OutOfMemoryError`ã
## åå¾åæ¶ç®æ³æåªäºï¼
åå¾åæ¶ç®æ³æåç§ï¼å嫿¯**æ è®°æ¸
餿³ãæ è®°æ´çæ³ãå¤å¶ç®æ³ãå代æ¶éç®æ³**ã
**æ è®°æ¸
é¤ç®æ³**
é¦å
å©ç¨å¯è¾¾æ§å»éåå
åï¼æåæ´»å¯¹è±¡ååå¾å¯¹è±¡è¿è¡æ è®°ãæ è®°ç»æåç»ä¸å°æææ è®°çå¯¹è±¡åæ¶æãè¿ç§åå¾åæ¶ç®æ³æçè¾ä½ï¼å¹¶ä¸ä¼**产ç大éä¸è¿ç»ç空é´ç¢ç**ã

**å¤å¶æ¸
é¤ç®æ³**
ååºå¤å¶ï¼ç¨äºæ°ç代åå¾åæ¶ãå°å
åå为大å°ç¸åç两åï¼æ¯æ¬¡ä½¿ç¨å
¶ä¸çä¸åãå½è¿ä¸åçå
å使ç¨å®åï¼å°±å°è¿åæ´»ç对象å¤å¶å°å¦ä¸åå»ï¼ç¶ååæä½¿ç¨ç空é´ä¸æ¬¡æ¸
çæã
ç¹ç¹ï¼å®ç°ç®åï¼è¿è¡é«æï¼ä½å¯ç¨å
å缩å°ä¸ºäºåæ¥çä¸åï¼æµªè´¹ç©ºé´ã
**æ è®°æ´çç®æ³**
æ ¹æ®è年代çç¹ç¹æåºçä¸ç§æ è®°ç®æ³ï¼æ è®°è¿ç¨ä»ç¶ä¸`æ è®°-æ¸
é¤`ç®æ³ä¸æ ·ï¼ä½åç»æ¥éª¤ä¸æ¯ç´æ¥å¯¹å¯åæ¶å¯¹è±¡è¿è¡æ¸
çï¼èæ¯è®©ææåæ´»ç对象é½åä¸ç«¯ç§»å¨ï¼ç¶åç´æ¥æ¸
çæè¾¹ç以å¤çå
åã

**åç±»æ¶éç®æ³**
æ ¹æ®å个年代çç¹ç¹éç¨æéå½çæ¶éç®æ³ã
ä¸è¬å°å å为æ°ç代åè年代ã
- æ°ç代使ç¨å¤å¶ç®æ³
- èå¹´ä»£ä½¿ç¨æ è®°æ¸
é¤ç®æ³æè
æ è®°æ´çç®æ³
卿°ç代ä¸ï¼æ¯æ¬¡å徿¶éæ¶é½æå¤§æ¹å¯¹è±¡æ»å»ï¼åªæå°éåæ´»ï¼ä½¿ç¨å¤å¶ç®æ³æ¯è¾åéï¼åªéè¦ä»åºå°éåæ´»å¯¹è±¡çå¤å¶ææ¬å°±å¯ä»¥å®ææ¶éãèå¹´ä»£å¯¹è±¡åæ´»çé«ï¼éåä½¿ç¨æ è®°-æ¸
çæè
æ è®°-æ´çç®æ³è¿è¡åå¾åæ¶ã
## æåªäºåå¾åæ¶å¨ï¼
åå¾åæ¶å¨ä¸»è¦å为以ä¸å ç§ï¼`SerialãParNewãParallel ScavengeãSerial OldãParallel OldãCMSãG1`ã
è¿7ç§å徿¶éå¨çç¹ç¹ï¼
| æ¶éå¨ | 串è¡ãå¹¶è¡orå¹¶å | æ°ç代/è年代 | ç®æ³ | ç®æ | éç¨åºæ¯ |
| :-------------------: | :--------------: | :-----------: | :----------------: | :----------: | :---------------------------------------: |
| **Serial** | ä¸²è¡ | æ°ç代 | å¤å¶ç®æ³ | ååºé度ä¼å
| åCPUç¯å¢ä¸çClientæ¨¡å¼ |
| **ParNew** | å¹¶è¡ | æ°ç代 | å¤å¶ç®æ³ | ååºé度ä¼å
| å¤CPUç¯å¢æ¶å¨Server模å¼ä¸ä¸CMSé
å |
| **Parallel Scavenge** | å¹¶è¡ | æ°ç代 | å¤å¶ç®æ³ | ååéä¼å
| å¨åå°è¿ç®èä¸éè¦å¤ªå¤äº¤äºçä»»å¡ |
| **Serial Old** | ä¸²è¡ | è年代 | æ è®°-æ´ç | ååºé度ä¼å
| åCPUç¯å¢ä¸çClient模å¼ãCMSçåå¤é¢æ¡ |
| **Parallel Old** | å¹¶è¡ | è年代 | æ è®°-æ´ç | ååéä¼å
| å¨åå°è¿ç®èä¸éè¦å¤ªå¤äº¤äºçä»»å¡ |
| **CMS** | å¹¶å | è年代 | æ è®°-æ¸
é¤ | ååºé度ä¼å
| éä¸å¨äºèç½ç«æB/Sç³»ç»æå¡ç«¯ä¸çJavaåºç¨ |
| **G1** | å¹¶å | both | æ è®°-æ´ç+å¤å¶ç®æ³ | ååºé度ä¼å
| é¢åæå¡ç«¯åºç¨ï¼å°æ¥æ¿æ¢CMS |
**Serial æ¶éå¨**
**åçº¿ç¨æ¶éå¨**ï¼ä½¿ç¨ä¸ä¸ªå徿¶é线ç¨å»è¿è¡åå¾åæ¶ï¼å¨è¿è¡åå¾åæ¶çæ¶åå¿
é¡»æåå
¶ä»ææçå·¥ä½çº¿ç¨ï¼ `Stop The World` ï¼ï¼ç´å°å®æ¶éç»æã
ç¹ç¹ï¼ç®å髿ï¼å
åæ¶èå°ï¼æ²¡æçº¿ç¨äº¤äºçå¼éï¼åçº¿ç¨æ¶éæçé«ï¼éæåææçå·¥ä½çº¿ç¨ï¼ç¨æ·ä½éªä¸å¥½ã
**ParNew æ¶éå¨**
`Serial`æ¶éå¨ç**å¤çº¿ç¨çæ¬**ï¼é¤äºä½¿ç¨å¤çº¿ç¨è¿è¡å徿¶éå¤ï¼å
¶ä»è¡ä¸ºãåæ°ä¸ `Serial` æ¶éå¨åºæ¬ä¸è´ã
**Parallel Scavenge æ¶éå¨**
**æ°ç代æ¶éå¨**ï¼åºäº**å¤å¶æ¸
é¤ç®æ³**å®ç°çæ¶éå¨ãç¹ç¹æ¯**ååéä¼å
**ï¼è½å¤å¹¶è¡æ¶éçå¤çº¿ç¨æ¶éå¨ï¼å
许å¤ä¸ªåå¾åæ¶çº¿ç¨åæ¶è¿è¡ï¼éä½å徿¶éæ¶é´ï¼æé«ååéãæè°ååéå°±æ¯ CPU ä¸ç¨äºè¿è¡ç¨æ·ä»£ç çæ¶é´ä¸ CPU æ»æ¶èæ¶é´çæ¯å¼ï¼`ååé = è¿è¡ç¨æ·ä»£ç æ¶é´ /ï¼è¿è¡ç¨æ·ä»£ç æ¶é´ + å徿¶éæ¶é´ï¼`ï¼ã`Parallel Scavenge` æ¶éå¨å
³æ³¨ç¹æ¯**ååéï¼é«æççå©ç¨ CPU èµæº**ã`CMS` å徿¶éå¨å
³æ³¨ç¹æ´å¤çæ¯**ç¨æ·çº¿ç¨çåé¡¿æ¶é´**ã
`Parallel Scavenge`æ¶é卿ä¾äºä¸¤ä¸ªåæ°ç¨äº**精确æ§å¶ååé**ï¼å嫿¯æ§å¶æå¤§å徿¶éåé¡¿æ¶é´ç`-XXï¼MaxGCPauseMillis`忰以åç´æ¥è®¾ç½®ååé大å°ç`-XXï¼GCTimeRatio`åæ°ã
- `-XXï¼MaxGCPauseMillis`åæ°ç弿¯ä¸ä¸ªå¤§äº0çæ¯«ç§æ°ï¼æ¶éå¨å°å°½éä¿è¯å
ååæ¶è±è´¹çæ¶é´ä¸è¶
è¿ç¨æ·è®¾å®å¼ã
- `-XXï¼GCTimeRatio`åæ°çå¼å¤§äº0å°äº100ï¼å³å徿¶éæ¶é´å æ»æ¶é´çæ¯çï¼ç¸å½äºååéçåæ°ã
**Serial Old æ¶éå¨**
`Serial` æ¶éå¨çèå¹´ä»£çæ¬ï¼åçº¿ç¨æ¶éå¨ï¼ä½¿ç¨**æ è®°æ´çç®æ³**ã
**Parallel Old æ¶éå¨**
`Parallel Scavenge` æ¶éå¨çèå¹´ä»£çæ¬ãå¤çº¿ç¨å徿¶éï¼ä½¿ç¨**æ è®°æ´çç®æ³**ã
**CMS æ¶éå¨**
`Concurrent Mark Sweep` ï¼å¹¶åæ è®°æ¸
é¤ï¼è¿½æ±è·å**æçåé¡¿æ¶é´**ï¼å®ç°äºè®©**å徿¶é线ç¨ä¸ç¨æ·çº¿ç¨åºæ¬ä¸åæ¶å·¥ä½**ã
`CMS` åå¾åæ¶åºäº**æ è®°æ¸
é¤ç®æ³**å®ç°ï¼æ´ä¸ªè¿ç¨å为å个æ¥éª¤ï¼
- åå§æ è®°ï¼ æåææç¨æ·çº¿ç¨ï¼`Stop The World`ï¼ï¼è®°å½ç´æ¥ä¸ `GC Roots` ç´æ¥ç¸è¿ç对象 ã
- å¹¶åæ è®°ï¼ä»`GC Roots`å¼å§å¯¹å ä¸å¯¹è±¡è¿è¡å¯è¾¾æ§åæï¼æ¾åºå活对象ï¼èæ¶è¾é¿ï¼ä½æ¯ä¸éè¦åé¡¿ç¨æ·çº¿ç¨ã
- éæ°æ è®°ï¼ å¨å¹¶åæ è®°æé´å¯¹è±¡çå¼ç¨å
³ç³»å¯è½ä¼ååï¼éè¦éæ°è¿è¡æ è®°ãæ¤é¶æ®µä¹ä¼æåææç¨æ·çº¿ç¨ã
- 并忏
é¤ï¼æ¸
餿 记对象ï¼è¿ä¸ªé¶æ®µä¹æ¯å¯ä»¥ä¸ç¨æ·çº¿ç¨åæ¶å¹¶åçã
卿´ä¸ªè¿ç¨ä¸ï¼èæ¶æé¿çæ¯å¹¶åæ è®°å并忏
é¤é¶æ®µï¼è¿ä¸¤ä¸ªé¶æ®µå徿¶é线ç¨é½å¯ä»¥ä¸ç¨æ·çº¿ç¨ä¸èµ·å·¥ä½ï¼æä»¥ä»æ»ä½ä¸æ¥è¯´ï¼`CMS`æ¶éå¨çå
ååæ¶è¿ç¨æ¯ä¸ç¨æ·çº¿ç¨ä¸èµ·å¹¶åæ§è¡çã
**ä¼ç¹**ï¼å¹¶åæ¶éï¼åé¡¿æ¶é´çã
**缺ç¹**ï¼
- æ è®°æ¸
é¤ç®æ³å¯¼è´æ¶éç»ææ**大é空é´ç¢ç**ã
- **äº§çæµ®å¨åå¾**ï¼å¨å¹¶åæ¸
çé¶æ®µç¨æ·çº¿ç¨è¿å¨è¿è¡ï¼ä¼ä¸æææ°çåå¾äº§çï¼è¿ä¸é¨ååå¾åºç°å¨æ è®°è¿ç¨ä¹åï¼`CMS`æ æ³å¨å½æ¬¡æ¶éä¸åæ¶å®ä»¬ï¼åªå¥½çå°ä¸ä¸æ¬¡åå¾åæ¶åå¤çï¼
**G1æ¶éå¨**
G1å徿¶éå¨çç®æ æ¯å¨ä¸ååºç¨åºæ¯ä¸**追æ±é«ååéåä½åé¡¿ä¹é´çæä½³å¹³è¡¡**ã
G1å°æ´ä¸ªå åæç¸å大å°çååºï¼`Region`ï¼ï¼æåç§ä¸åç±»åçååºï¼`EdenãSurvivorãOldåHumongous`ãååºç大å°åå¼èå´ä¸º 1M å° 32Mï¼é½æ¯2ç广¬¡æ¹ãååºå¤§å°å¯ä»¥éè¿`-XX:G1HeapRegionSize`åæ°æå®ã`Humongous`åºåç¨äºåå¨å¤§å¯¹è±¡ãG1è§å®åªè¦å¤§å°è¶
è¿äºä¸ä¸ªååºå®¹éä¸åç对象就认为æ¯å¤§å¯¹è±¡ã

G1 æ¶éå¨å¯¹å个ååºåæ¶æè·å¾ç空é´å¤§å°ååæ¶æéæ¶é´çç»éªå¼è¿è¡æåºï¼å¾å°ä¸ä¸ªä¼å
级åè¡¨ï¼æ¯æ¬¡æ ¹æ®ç¨æ·è®¾ç½®çæå¤§åæ¶åé¡¿æ¶é´ï¼ä¼å
忶价弿大çååºã
**ç¹ç¹**ï¼å¯ä»¥ç±ç¨æ·**æå®**ææçå徿¶éåé¡¿æ¶é´ã
G1 æ¶éå¨çåæ¶è¿ç¨å为以ä¸å 个æ¥éª¤ï¼
- **åå§æ è®°**ãæåææå
¶ä»çº¿ç¨ï¼è®°å½ç´æ¥ä¸ `GC Roots` ç´æ¥ç¸è¿ç对象ï¼èæ¶è¾ç ã
- **å¹¶åæ è®°**ãä»`GC Roots`å¼å§å¯¹å ä¸å¯¹è±¡è¿è¡å¯è¾¾æ§åæï¼æ¾åºè¦åæ¶ç对象ï¼èæ¶è¾é¿ï¼ä¸è¿å¯ä»¥åç¨æ·ç¨åºå¹¶åæ§è¡ã
- **æç»æ è®°**ãé对å
¶ä»çº¿ç¨åçæçæåï¼ç¨äºå¤çå¹¶åæ è®°é¶æ®µå¯¹è±¡å¼ç¨åºç°åå¨çåºåã
- **çéåæ¶**ã对å个ååºçåæ¶ä»·å¼åææ¬è¿è¡æåºï¼æ ¹æ®ç¨æ·æææçåé¡¿æ¶é´æ¥å¶å®åæ¶è®¡åï¼ç¶åæå³å®åæ¶çååºçåæ´»å¯¹è±¡å¤å¶å°ç©ºçååºä¸ï¼åæ¸
çææ´ä¸ªæ§çååºçå
¨é¨ç©ºé´ãè¿éçæä½æ¶ååæ´»å¯¹è±¡çç§»å¨ï¼ä¼æåç¨æ·çº¿ç¨ï¼ç±å¤æ¡æ¶éå¨çº¿ç¨å¹¶è¡å®æã
## 常ç¨ç JVM è°ä¼çå½ä»¤é½æåªäºï¼
**jps**ï¼ååºæ¬æºææ Java è¿ç¨ç**è¿ç¨å·**ã
常ç¨åæ°å¦ä¸ï¼
- `-m` è¾åº`main`æ¹æ³çåæ°
- `-l` è¾åºå®å
¨çå
åååºç¨ä¸»ç±»å
- `-v` è¾åº`JVM`åæ°
```java
jps -lvm
//output
//4124 com.zzx.Application -javaagent:E:\IDEA2019\lib\idea_rt.jar=10291:E:\IDEA2019\bin -Dfile.encoding=UTF-8
```
**jstack**ï¼æ¥çæä¸ª Java è¿ç¨å
ç**线ç¨å æ ä¿¡æ¯**ã使ç¨åæ°`-l`å¯ä»¥æå°é¢å¤çéä¿¡æ¯ï¼åçæ»éæ¶å¯ä»¥ä½¿ç¨`jstack -l pid`è§å¯éæææ
åµã
```java
jstack -l 4124 | more
```
è¾åºç»æå¦ä¸ï¼
```java
"http-nio-8001-exec-10" #40 daemon prio=5 os_prio=0 tid=0x000000002542f000 nid=0x4028 waiting on condition [0x000000002cc9e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000077420d7e8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
```
`WAITING (parking)`æçº¿ç¨å¤äºæèµ·ä¸ï¼å¨çå¾
æä¸ªæ¡ä»¶åçï¼æ¥æèªå·±å¤éã
**jstat**ï¼ç¨äºæ¥çèææºåç§**è¿è¡ç¶æä¿¡æ¯ï¼ç±»è£
è½½ãå
åãå徿¶éçè¿è¡æ°æ®ï¼**ã使ç¨åæ°`-gcuitl`å¯ä»¥æ¥çåå¾åæ¶çç»è®¡ä¿¡æ¯ã
```java
jstat -gcutil 4124
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 67.21 19.20 96.36 94.96 10 0.084 3 0.191 0.275
```
åæ°è¯´æï¼
- **S0**ï¼`Survivor0`åºå½åä½¿ç¨æ¯ä¾
- **S1**ï¼`Survivor1`åºå½åä½¿ç¨æ¯ä¾
- **E**ï¼`Eden`åºä½¿ç¨æ¯ä¾
- **O**ï¼èå¹´ä»£ä½¿ç¨æ¯ä¾
- **M**ï¼å
æ°æ®åºä½¿ç¨æ¯ä¾
- **CCS**ï¼åç¼©ä½¿ç¨æ¯ä¾
- **YGC**ï¼å¹´è½»ä»£åå¾åæ¶æ¬¡æ°
- **FGC**ï¼è年代åå¾åæ¶æ¬¡æ°
- **FGCT**ï¼è年代åå¾åæ¶æ¶èæ¶é´
- **GCT**ï¼åå¾åæ¶æ¶èæ»æ¶é´
**jmap**ï¼æ¥ç**å å
åå¿«ç
§**ãéè¿`jmap`å½ä»¤å¯ä»¥è·å¾è¿è¡ä¸çå å
åçå¿«ç
§ï¼ä»èå¯ä»¥å¯¹å å
åè¿è¡ç¦»çº¿åæã
æ¥è¯¢è¿ç¨4124çå å
åå¿«ç
§ï¼è¾åºç»æå¦ä¸ï¼
```java
>jmap -heap 4124
Attaching to process ID 4124, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.221-b11
using thread-local object allocation.
Parallel GC with 6 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 4238344192 (4042.0MB)
NewSize = 88604672 (84.5MB)
MaxNewSize = 1412431872 (1347.0MB)
OldSize = 177733632 (169.5MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 327155712 (312.0MB)
used = 223702392 (213.33922576904297MB)
free = 103453320 (98.66077423095703MB)
68.37795697725736% used
From Space:
capacity = 21495808 (20.5MB)
used = 0 (0.0MB)
free = 21495808 (20.5MB)
0.0% used
To Space:
capacity = 23068672 (22.0MB)
used = 0 (0.0MB)
free = 23068672 (22.0MB)
0.0% used
PS Old Generation
capacity = 217579520 (207.5MB)
used = 41781472 (39.845916748046875MB)
free = 175798048 (167.65408325195312MB)
19.20285144484187% used
27776 interned Strings occupying 3262336 bytes.
```
**jinfo**ï¼`jinfo -flags 1`ãæ¥çå½åçåºç¨JVMåæ°é
ç½®ã
```java
Attaching to process ID 1, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.111-b14
Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=31457280 -XX:MaxHeapSize=480247808 -XX:MaxNewSize=160038912 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=10485760 -XX:OldSize=20971520 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops
Command line:
```
**æ¥çææåæ°**ï¼`java -XX:+PrintFlagsFinal -version`ãç¨äºæ¥çæç»å¼ï¼åå§å¼å¯è½è¢«ä¿®æ¹æï¼æ¥çåå§å¼å¯ä»¥ä½¿ç¨java -XX:+PrintFlagsInitialï¼ã
```java
[Global flags]
uintx AdaptiveSizeDecrementScaleFactor = 4 {product}
uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product}
uintx AdaptiveSizePausePolicy = 0 {product}
uintx AdaptiveSizePolicyCollectionCostMargin = 50 {product}
uintx AdaptiveSizePolicyInitializingSteps = 20 {product}
uintx AdaptiveSizePolicyOutputInterval = 0 {product}
uintx AdaptiveSizePolicyWeight = 10 {product}
uintx AdaptiveSizeThroughPutPolicy = 0 {product}
uintx AdaptiveTimeWeight = 25 {product}
bool AdjustConcurrency = false {product}
bool AggressiveOpts = false {product}
....
```
## 对象头äºè§£åï¼
Java å
åä¸ç对象ç±ä»¥ä¸ä¸é¨åç»æï¼**对象头**ã**å®ä¾æ°æ®**å**对é½å¡«å
åè**ã
è对象头ç±ä»¥ä¸ä¸é¨åç»æï¼**mark word**ã**æå类信æ¯çæé**å**æ°ç»é¿åº¦**ï¼æ°ç»ææï¼ã
`mark word`å
å«ï¼å¯¹è±¡çåå¸ç ãå代年é¾åéæ å¿ä½ã
对象çå®ä¾æ°æ®å°±æ¯ Java 对象ç屿§åå¼ã
对é½å¡«å
åèï¼å 为JVMè¦æ±å¯¹è±¡å çå
å大尿¯ 8bit çåæ°ï¼å æ¤å颿å 个åèç¨äºæå¯¹è±¡ç大å°è¡¥é½è³ 8bit çåæ°ã
**å
å对é½ç主è¦ä½ç¨æ¯ï¼**
1. å¹³å°åå ï¼ä¸æ¯ææç硬件平å°é½è½è®¿é®ä»»æå°åä¸çä»»ææ°æ®çï¼æäºç¡¬ä»¶å¹³å°åªè½å¨æäºå°åå¤åæäºç¹å®ç±»åçæ°æ®ï¼å¦åæåºç¡¬ä»¶å¼å¸¸ã
2. æ§è½åå ï¼ç»è¿å
å对é½åï¼CPUçå
å访é®é度大大æåã
## Object o = new Object()å ç¨å¤å°ä¸ªåèï¼
çæ¡æ¯16个åèã
é¦å
å
åæå¯¹è±¡çå
åå¸å±ã
å¨ JVM ä¸ï¼Java对象ä¿åå¨å 䏿¶ï¼ç±ä»¥ä¸ä¸é¨åç»æï¼
**对象头ï¼Object Headerï¼**ï¼å
æ¬å
³äºå 对象çå¸å±ãç±»åãGCç¶æãåæ¥ç¶æåæ è¯åå¸ç çåºæ¬ä¿¡æ¯ãç±ä¸¤ä¸ªè¯`mark word`å`classpointer`ç»æï¼å¦ææ¯æ°ç»å¯¹è±¡çè¯ï¼è¿ä¼æä¸ä¸ª`length field`ã
- mark wordï¼é常æ¯ä¸ç»ä½åï¼ç¨äºåå¨å¯¹è±¡èªèº«çè¿è¡æ¶æ°æ®ï¼å¦hashCodeãGCå代年é¾ãéåæ¥ä¿¡æ¯ççãå ç¨64个æ¯ç¹ï¼64ä½ç³»ç»ï¼ï¼8个åèã
- classpointerï¼ç±»æéï¼æ¯å¯¹è±¡æåå®çç±»å
æ°æ®çæéï¼èææºéè¿è¿ä¸ªæéæ¥ç¡®å®è¿ä¸ªå¯¹è±¡æ¯åªä¸ªç±»çå®ä¾ãå ç¨64个æ¯ç¹ï¼64ä½ç³»ç»ï¼ï¼8个åèãå¼å¯å缩类æéåï¼å ç¨32个æ¯ç¹ï¼4个åèã
**å®ä¾æ°æ®ï¼Instance Dataï¼**ï¼åå¨äºä»£ç ä¸å®ä¹çåç§å段çå
容ï¼å
æ¬ä»ç¶ç±»ç»§æ¿ä¸æ¥çåæ®µååç±»ä¸å®ä¹çåæ®µãå¦æå¯¹è±¡æ 屿§å段ï¼åè¿éå°±ä¸ä¼ææ°æ®ãæ ¹æ®å段类åçä¸åå ä¸åçåèï¼ä¾å¦booleanç±»åå 1个åèï¼intç±»åå 4个åèççãä¸ºäºæé«åå¨ç©ºé´çå©ç¨çï¼è¿é¨åæ°æ®çåå¨é¡ºåºä¼åå°èææºåé
çç¥åæ°ååæ®µå¨Javaæºç ä¸å®ä¹é¡ºåºçå½±åã
**对é½å¡«å
ï¼Paddingï¼**ï¼å¯¹è±¡å¯ä»¥æå¯¹é½æ°æ®ä¹å¯ä»¥æ²¡æãé»è®¤æ
åµä¸ï¼Javaèææºå ä¸å¯¹è±¡çèµ·å§å°åéè¦å¯¹é½è³8çæ´æ°åã妿ä¸ä¸ªå¯¹è±¡ç对象头åå®ä¾æ°æ®å ç¨çæ»å¤§å°ä¸å°8åèçæ´æ°åï¼åä»¥æ¤æ¥å¡«å
对象大å°è³8åèçæ´æ°åã
> **为ä»ä¹è¦å¯¹é½å¡«å
**ï¼å段å
å对é½çå
¶ä¸ä¸ä¸ªåå ï¼æ¯è®©å段åªåºç°å¨åä¸CPUçç¼åè¡ä¸ã妿忮µä¸æ¯å¯¹é½çï¼é£ä¹å°±æå¯è½åºç°è·¨ç¼åè¡çåæ®µãä¹å°±æ¯è¯´ï¼è¯¥å段ç读åå¯è½éè¦æ¿æ¢ä¸¤ä¸ªç¼åè¡ï¼èè¯¥åæ®µçåå¨ä¹ä¼åæ¶æ±¡æä¸¤ä¸ªç¼åè¡ãè¿ä¸¤ç§æ
åµå¯¹ç¨åºçæ§è¡æçèè¨é½æ¯ä¸å©çãå
¶å®å¯¹å
¶å¡«å
çæç»ç®çæ¯ä¸ºäºè®¡ç®æº**髿坻å**ã
ç»è¿ä¸é¢çåæä¹åï¼å°±å¯ä»¥ç¥éObject o = new Object()å
·ä½å ç¨å¤å°å
åäºï¼ä»¥64ä½ç³»ç»ä¸ºä¾ï¼ã
- **å¨å¼å¯æéå缩çæ
åµä¸**ï¼markwordå ç¨8åèï¼classpointerå ç¨4åèï¼Instance dataæ æ°æ®ï¼æ»å
±æ¯12åèï¼ç±äºå¯¹è±¡éè¦ä¸º8çæ´æ°åï¼Paddingä¼è¡¥å
4个åèï¼æ»å
±å ç¨16åèã
- **卿²¡æå¼å¯æéå缩çæ
åµä¸**ï¼markwordå ç¨8åèï¼classpointerå ç¨8åèï¼Instance dataæ æ°æ®ï¼ä¹æ¯å ç¨16åèã
## mainæ¹æ³æ§è¡è¿ç¨
以䏿¯ç¤ºä¾ä»£ç ï¼
```java
public class Application {
public static void main(String[] args) {
Person p = new Person("大彬");
p.getName();
}
}
class Person {
public String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
```
æ§è¡`main`æ¹æ³çè¿ç¨å¦ä¸:
1. ç¼è¯`Application.java`åå¾å° `Application.class` åï¼æ§è¡è¿ä¸ª`class`æä»¶ï¼ç³»ç»ä¼å¯å¨ä¸ä¸ª `JVM` è¿ç¨ï¼ä»ç±»è·¯å¾ä¸æ¾å°ä¸ä¸ªå为 `Application.class` çäºè¿å¶æä»¶ï¼å° `Application` 类信æ¯å è½½å°è¿è¡æ¶æ°æ®åºçæ¹æ³åºå
ï¼è¿ä¸ªè¿ç¨å«åç±»çå è½½ã
2. JVM æ¾å° `Application` ç主ç¨åºå
¥å£ï¼æ§è¡`main`æ¹æ³ã
3. `main`æ¹æ³çç¬¬ä¸æ¡è¯å¥ä¸º `Person p = new Person("大彬") `ï¼å°±æ¯è®© JVM å建ä¸ä¸ª`Person`对象ï¼ä½æ¯è¿ä¸ªæ¶åæ¹æ³åºä¸æ¯æ²¡æ `Person` ç±»çä¿¡æ¯çï¼æä»¥ JVM 马ä¸å è½½ `Person` ç±»ï¼æ `Person` ç±»çä¿¡æ¯æ¾å°æ¹æ³åºä¸ã
4. å è½½å® `Person` ç±»åï¼JVM å¨å ä¸åé
å
åç» `Person` 对象ï¼ç¶åè°ç¨æé 彿°åå§å `Person` 对象ï¼è¿ä¸ª `Person` 对象ææ**æåæ¹æ³åºä¸ç Person ç±»çç±»åä¿¡æ¯**çå¼ç¨ã
5. æ§è¡`p.getName()`æ¶ï¼JVM æ ¹æ® p çå¼ç¨æ¾å° p ææåç对象ï¼ç¶åæ ¹æ®æ¤å¯¹è±¡ææçå¼ç¨å®ä½å°æ¹æ³åºä¸ `Person` ç±»çç±»åä¿¡æ¯çæ¹æ³è¡¨ï¼è·å¾ `getName()` çåèç å°åã
6. æ§è¡`getName()`æ¹æ³ã
## 对象å建è¿ç¨
1. **ç±»å è½½æ£æ¥**ï¼å½èææºéå°ä¸æ¡ `new` æä»¤æ¶ï¼é¦å
æ£æ¥æ¯å¦è½å¨å¸¸éæ± ä¸å®ä½å°è¿ä¸ªç±»ç符å·å¼ç¨ï¼å¹¶ä¸æ£æ¥è¿ä¸ªç¬¦å·å¼ç¨ä»£è¡¨çç±»æ¯å¦å·²è¢«å è½½è¿ãè§£æååå§åè¿ãå¦ææ²¡æï¼é£å
æ§è¡ç±»å è½½ã
2. **åé
å
å**ï¼å¨ç±»å è½½æ£æ¥éè¿åï¼æ¥ä¸æ¥èææºå°ä¸ºå¯¹è±¡å®ä¾åé
å
åã
3. **åå§å**ãåé
å°çå
å空é´é½åå§å为é¶å¼ï¼éè¿è¿ä¸ªæä½ä¿è¯äºå¯¹è±¡çåæ®µå¯ä»¥ä¸èµåå§å¼å°±ç´æ¥ä½¿ç¨ï¼ç¨åºè½è®¿é®å°è¿äºåæ®µçæ°æ®ç±»åæå¯¹åºçé¶å¼ã
4. **设置对象头**ã`Hotspot` èææºç对象头å
æ¬ï¼åå¨å¯¹è±¡èªèº«çè¿è¡æ¶æ°æ®ï¼åå¸ç ãå代年é¾ãéæ å¿ççï¼ãç±»åæéåæ°æ®é¿åº¦ï¼æ°ç»å¯¹è±¡ææï¼ï¼ç±»åæéå°±æ¯å¯¹è±¡æåå®ç类信æ¯çæéï¼èææºéè¿è¿ä¸ªæéæ¥ç¡®å®è¿ä¸ªå¯¹è±¡æ¯åªä¸ªç±»çå®ä¾ã
5. **æç
§`Java`代ç è¿è¡åå§å**ã
## å¦ä½ææ¥ OOM çé®é¢ï¼
> 线ä¸JVMå¿
é¡»é
ç½®`-XX:+HeapDumpOnOutOfMemoryError` å`-XX:HeapDumpPath=/tmp/heapdump.hprof`ï¼å½OOMåçæ¶èªå¨ dump å å
åä¿¡æ¯å°æå®ç®å½
ææ¥ OOM çæ¹æ³å¦ä¸ï¼
- æ¥çæå¡å¨è¿è¡æ¥å¿æ¥å¿ï¼ææå°å
åæº¢åºå¼å¸¸
- jstat æ¥ççæ§JVMçå
ååGCæ
åµï¼è¯ä¼°é®é¢å¤§æ¦åºå¨ä»ä¹åºå
- 使ç¨MATå·¥å
·è½½å
¥dumpæä»¶ï¼åæå¤§å¯¹è±¡çå ç¨æ
åµ
## ä»ä¹æ¯å
åæº¢åºåå
åæ³é²ï¼
å
åæº¢åºæçæ¯ç¨åºç³è¯·å
åæ¶ï¼**没æè¶³å¤çå
å**ä¾ç³è¯·è
使ç¨ï¼æ¯å¦ç»äºä½ ä¸ååå¨intç±»åæ°æ®çåå¨ç©ºé´ï¼ä½æ¯ä½ å´åå¨longç±»åçæ°æ®ï¼é£ä¹ç»æå°±æ¯å
åä¸å¤ç¨ï¼æ¤æ¶å°±ä¼æ¥éOOMï¼å³å
åæº¢åºã
å
忳鲿¯æç¨åºä¸é´å¨æåé
äºå
åï¼ä½å¨ç¨åºç»ææ¶æ²¡æéæ¾è¿é¨åå
åï¼ä»èé æé£é¨å**å
åä¸å¯ç¨**çæ
åµãè¿ç§æ
åµéå¯è®¡ç®æºå¯ä»¥è§£å³ï¼ä½ä¹æå¯è½å次åçå
åæ³é²ãå
åæ³é²å硬件没æå
³ç³»ï¼å®æ¯ç±è½¯ä»¶è®¾è®¡ç¼ºé·å¼èµ·çã
åIOæä½æè
ç½ç»è¿æ¥çï¼å¨ä½¿ç¨å®æä¹å没æè°ç¨close()æ¹æ³å°å
¶è¿æ¥å
³éï¼é£ä¹å®ä»¬å ç¨çå
忝ä¸ä¼èªå¨è¢«GCåæ¶çï¼æ¤æ¶å°±ä¼äº§çå
åæ³é²ã
æ¯å¦æä½æ°æ®åºæ¶ï¼éè¿SessionFactoryè·åä¸ä¸ªsessionï¼
```java
Session session=sessionFactory.openSession();
```
宿åæä»¬å¿
é¡»è°ç¨session.close()æ¹æ³å
³éï¼å¦åå°±ä¼äº§çå
åæ³é²ï¼å 为sessionFactoryè¿ä¸ªé¿çå½å¨æå¯¹è±¡ä¸ç´ææsessionè¿ä¸ªççå½å¨æå¯¹è±¡çå¼ç¨ã
é£ä¸¤è
æä»ä¹ä¸åå¢ï¼
å
åæ³é²å¯ä»¥éè¿å®åä»£ç æ¥é¿å
ï¼å
åæº¢åºå¯ä»¥éè¿è°æ´é
ç½®æ¥åå°åçé¢çï¼ä½æ æ³å½»åºé¿å
ã
å¦ä½é¿å
å
åæ³é²å溢åºå¢ï¼
1. **å°½æ©éæ¾æ ç¨å¯¹è±¡çå¼ç¨**ãæ¯å¦ä½¿ç¨ä¸´æ¶åéçæ¶åï¼è®©å¼ç¨åéå¨éåºæ´»å¨ååèªå¨è®¾ç½®ä¸ºnullï¼æç¤ºå徿¶é卿¥æ¶é该对象ï¼é²æ¢åçå
åæ³é²ã
2. **å°½éå°ç¨éæåé**ãå 为éæå鿝å
¨å±çï¼GCä¸ä¼åæ¶ã
3. **é¿å
éä¸å建对象尤å
¶æ¯å¤§å¯¹è±¡**ï¼å¦æå¯ä»¥çè¯å°½éä½¿ç¨æµæä½ã
4. å°½éè¿ç¨**æ± åææ¯**ï¼æ°æ®åºè¿æ¥æ± çï¼ä»¥æé«ç³»ç»æ§è½ã
5. **é¿å
å¨å¾ªç¯ä¸å建è¿å¤å¯¹è±¡**ã
**åèèµæ**
- å¨å¿æ. æ·±å
¥çè§£ Java èææº [M]. æºæ¢°å·¥ä¸åºç社
