**ææé®é¢ä»¥åçæ¡ï¼æé½æ´çæäºé«æ¸
PDFï¼å¹¶ä¸å¸¦ç®å½ï¼[Javaé¢è¯æ´ç髿¸
PDFä¸è½½](https://gitee.com/tiger-a/java-interview/blob/master/interviewDoc/Java/index.md)**
**ææé®é¢ä»¥åçæ¡ï¼æé½æ´çæäºé«æ¸
PDFï¼å¹¶ä¸å¸¦ç®å½ï¼[Javaé¢è¯æ´ç髿¸
PDFä¸è½½](https://gitee.com/tiger-a/java-interview/blob/master/interviewDoc/Java/index.md)**
**ææé®é¢ä»¥åçæ¡ï¼æé½æ´çæäºé«æ¸
PDFï¼å¹¶ä¸å¸¦ç®å½ï¼[Javaé¢è¯æ´ç髿¸
PDFä¸è½½](https://gitee.com/tiger-a/java-interview/blob/master/interviewDoc/Java/index.md)**
- [对象å¨åªåå
ååé
ï¼](#对象å¨åªåå
ååé
)
- [è°è° JVM ä¸ç叏鿱 ](#è°è°-jvm-ä¸ç叏鿱 )
- [è°è°å¨æå¹´é¾å¤æ](#è°è°å¨æå¹´é¾å¤æ)
- [è°è°æ°¸ä¹
代](#è°è°æ°¸ä¹
代)
- [JVM æåªäºè¿è¡æ¶å
ååºåï¼](#jvm-æåªäºè¿è¡æ¶å
ååºå)
- [è¿è¡æ¶æ 帧å
å«åªäºç»æï¼](#è¿è¡æ¶æ 帧å
å«åªäºç»æ)
- [JVM å¦ä½ç¡®å®åå¾å¯¹è±¡ï¼](#jvm-å¦ä½ç¡®å®åå¾å¯¹è±¡)
- [åªäºæ¯ GC Rootsï¼](#åªäºæ¯-gc-roots)
- [å¦ä½å¼å¯åæ¥ç GC æ¥å¿ï¼](#å¦ä½å¼å¯åæ¥ç-gc-æ¥å¿)
- [说ä¸ä¸åå¾å代æ¶éçè¿ç¨](#说ä¸ä¸åå¾å代æ¶éçè¿ç¨)
- [å¦ä½æ¾å°æ»éç线ç¨ï¼](#å¦ä½æ¾å°æ»éç线ç¨)
- [invokedynamic æä»¤æ¯å¹²ä»ä¹çï¼](#invokedynamic-æä»¤æ¯å¹²ä»ä¹ç)
- [ä»ä¹æ¯éé¸åæï¼](#ä»ä¹æ¯éé¸åæ)
- [ä»ä¹æ¯æ¹æ³å
èï¼](#ä»ä¹æ¯æ¹æ³å
è)
- [JVM çæ§ä¸åæå·¥å
·ä½ ç¨è¿åªäºï¼ä»ç»ä¸ä¸ã](#jvm-çæ§ä¸åæå·¥å
·ä½ ç¨è¿åªäºä»ç»ä¸ä¸)
- [æè¿°ä¸ä¸ä»ä¹æ
åµä¸ï¼å¯¹è±¡ä¼ä»å¹´è½»ä»£è¿å
¥è年代](#æè¿°ä¸ä¸ä»ä¹æ
åµä¸å¯¹è±¡ä¼ä»å¹´è½»ä»£è¿å
¥è年代)
- [å·¥ä½ä¸å¸¸ç¨ç JVM é
ç½®åæ°æåªäºï¼](#å·¥ä½ä¸å¸¸ç¨ç-jvm-é
ç½®åæ°æåªäº)
- [JIT æ¯ä»ä¹ï¼](#jit-æ¯ä»ä¹)
- [è°è°å¯¹ OOM ç认è¯](#è°è°å¯¹-oom-ç认è¯)
- [ä½ æåªäºææ®µæ¥ææ¥ OOM çé®é¢ï¼](#ä½ æåªäºææ®µæ¥ææ¥-oom-çé®é¢)
- [ä»ä¹æ
åµåçæ æº¢åºï¼](#ä»ä¹æ
åµåçæ æº¢åº)
- [éå°è¿å å¤å
åæº¢åºåï¼](#éå°è¿å å¤å
åæº¢åºå)
- [éå°è¿å
ç©ºé´æº¢åºåï¼](#éå°è¿å
ç©ºé´æº¢åºå)
- [被å¼ç¨ç对象就ä¸å®è½åæ´»åï¼](#被å¼ç¨ç对象就ä¸å®è½åæ´»å)
- [ä½ åè¿ JVM è°ä¼ï¼è¯´è¯´å¦ä½æ¥ç JVM åæ°é»è®¤å¼ï¼](#ä½ åè¿-jvm-è°ä¼è¯´è¯´å¦ä½æ¥ç-jvm-åæ°é»è®¤å¼)
- [ä»ä¹æ¯åèç ï¼éç¨åèç çæå¤§å¥½å¤æ¯ä»ä¹](#ä»ä¹æ¯åèç éç¨åèç çæå¤§å¥½å¤æ¯ä»ä¹)
- [ä»ä¹æ
åµä¸ä¼åçæ å
åæº¢åºã](#ä»ä¹æ
åµä¸ä¼åçæ å
åæº¢åº)
- [详解JVMå
忍¡å](#详解jvmå
忍¡å)
- [JVMå
å为ä»ä¹è¦åææ°ç代ï¼èå¹´ä»£ï¼æä¹
ä»£ãæ°ç代ä¸ä¸ºä»ä¹è¦å为EdenåSurvivorã](#jvmå
å为ä»ä¹è¦åææ°ç代è年代æä¹
代æ°ç代ä¸ä¸ºä»ä¹è¦å为edenåsurvivor)
- [JVMä¸ä¸æ¬¡å®æ´çGCæµç¨æ¯ææ ·çï¼å¯¹è±¡å¦ä½æåå°è年代](#jvmä¸ä¸æ¬¡å®æ´çgcæµç¨æ¯ææ ·ç对象å¦ä½æåå°è年代)
- [ä½ ç¥éåªå ç§å徿¶éå¨ï¼åèªçä¼ç¼ºç¹ï¼éç¹è®²ä¸cmsåG1ï¼å
æ¬åçï¼æµç¨ï¼ä¼ç¼ºç¹ã](#ä½ ç¥éåªå ç§å徿¶éå¨åèªçä¼ç¼ºç¹éç¹è®²ä¸cmsåg1å
æ¬åçæµç¨ä¼ç¼ºç¹)
- [å¦ä½æ¥ç JVM å½å使ç¨çæ¯ä»ä¹å徿¶éå¨ï¼](#å¦ä½æ¥ç-jvm-å½å使ç¨çæ¯ä»ä¹å徿¶éå¨)
- [JVMå
忍¡åçç¸å
³ç¥è¯äºè§£å¤å°ï¼æ¯å¦éæåºï¼å
åå±éï¼happen-beforeï¼ä¸»å
åï¼å·¥ä½å
åã](#jvmå
忍¡åçç¸å
³ç¥è¯äºè§£å¤å°æ¯å¦éæåºå
åå±éhappen-before主å
åå·¥ä½å
å)
- [è°è°ä½ ç¥éçåå¾åæ¶ç®æ³](#è°è°ä½ ç¥éçåå¾åæ¶ç®æ³)
- [è°è°ä½ ç¥éçå徿¶éå¨](#è°è°ä½ ç¥éçå徿¶éå¨)
- [ç产ç¯å¢ç¨çä»ä¹JDKï¼å¦ä½é
ç½®çå徿¶éå¨ï¼](#ç产ç¯å¢ç¨çä»ä¹jdkå¦ä½é
ç½®çå徿¶éå¨)
- [è°è°åäº²å§æ´¾æ¨¡å](#è°è°åäº²å§æ´¾æ¨¡å)
- [ç®åè¯´è¯´ä½ äºè§£çç±»å è½½å¨ï¼å¯ä»¥æç ´åäº²å§æ´¾ä¹ï¼æä¹æç ´ã](#ç®åè¯´è¯´ä½ äºè§£çç±»å è½½å¨å¯ä»¥æç ´åäº²å§æ´¾ä¹æä¹æç ´)
- [å举ä¸äºä½ ç¥éçæç ´åäº²å§æ´¾æºå¶çä¾åã为ä»ä¹è¦æç ´ï¼](#å举ä¸äºä½ ç¥éçæç ´åäº²å§æ´¾æºå¶çä¾å为ä»ä¹è¦æç ´)
- [æä¹æåºçº¿ç¨æ ä¿¡æ¯ã](#æä¹æåºçº¿ç¨æ ä¿¡æ¯)
- [强å¼ç¨ã软å¼ç¨ãå¼±å¼ç¨ãèå¼ç¨çåºå«ï¼](#强å¼ç¨è½¯å¼ç¨å¼±å¼ç¨èå¼ç¨çåºå«)
- [safepoint æ¯ä»ä¹ï¼](#safepoint-æ¯ä»ä¹)
- [MinorGCãMajorGCãFullGC ä»ä¹æ¶ååçï¼](#minorgcmajorgcfullgc-ä»ä¹æ¶ååç)
- [说说类å è½½çè¿ç¨](#说说类å è½½çè¿ç¨)
- [å¯ä»¥æè¿°ä¸ä¸ class æä»¶çç»æåï¼](#å¯ä»¥æè¿°ä¸ä¸-class-æä»¶çç»æå)
- [说说 JVM å¦ä½æ§è¡ class ä¸çåèç ã](#说说-jvm-å¦ä½æ§è¡-class-ä¸çåèç )
- [ç产ç¯å¢ CPU å ç¨è¿é«ï¼ä½ å¦ä½è§£å³ï¼](#ç产ç¯å¢-cpu-å ç¨è¿é«ä½ å¦ä½è§£å³)
- [ç产ç¯å¢æå¡å¨åæ
¢ï¼å¦ä½è¯æå¤çï¼](#ç产ç¯å¢æå¡å¨åæ
¢å¦ä½è¯æå¤ç)
### 对象å¨åªåå
ååé
ï¼
æ°ç»å对象å¨å å
ååé
ï¼æäºå¯¹è±¡æ²¡æéé¸åºæ¹æ³ï¼å¯è½è¢«ä¼åä¸ºå¨æ ä¸åé
### è°è° JVM ä¸ç叏鿱
**JDK 1.8 å¼å§**
åç¬¦ä¸²å¸¸éæ± ï¼åæ¾å¨å ä¸ï¼å
æ¬ String 对象æ§è¡ intern() æ¹æ³ååçå°æ¹ãåå¼å·ç´æ¥å¼ç¨çå符串
è¿è¡æ¶å¸¸éæ± ï¼åæ¾å¨æ¹æ³åºï¼å±äºå
空é´ï¼æ¯ç±»å è½½åçä¸äºåå¨åºåï¼å¤§å¤æ°æ¯ç±»ä¸ constant_pool çå
容
ç±»æä»¶å¸¸éæ± ï¼constant_poolï¼JVM å®ä¹çæ¦å¿µ
### è°è°å¨æå¹´é¾å¤æ
è¿éæ¶åå° `-XX:TargetSurvivorRatio` åæ°ï¼Survivor åºçç®æ 使ç¨çé»è®¤ 50ï¼å³ Survivor åºå¯¹è±¡ç®æ 使ç¨ç为 50%ã
Survivor åºç¸å年龿æå¯¹è±¡å¤§å°çæ»å > (Survivor åºå
åå¤§å° * è¿ä¸ªç®æ 使ç¨ç)æ¶ï¼å¤§äºæçäºè¯¥å¹´é¾çå¯¹è±¡ç´æ¥è¿å
¥è年代ã
å½ç¶ï¼è¿éè¿éè¦èèåæ° `-XX:MaxTenuringThreshold` æå年龿大éå¼
### è°è°æ°¸ä¹
代
JDK 8 ä¹åï¼Hotspot 䏿¹æ³åºçå®ç°æ¯æ°¸ä¹
代ï¼Permï¼
JDK 7 å¼å§æåæ¬æ¾å¨æ°¸ä¹
代çåç¬¦ä¸²å¸¸éæ± ãéæåéçç§»åºå°å ï¼JDK 8 å¼å§å»é¤æ°¸ä¹
代ï¼ä½¿ç¨å
空é´ï¼Metaspaceï¼ï¼æ°¸ä¹
代å©ä½å
容移è³å
空é´ï¼å
空é´ç´æ¥å¨æ¬å°å
ååé
ã
### JVM æåªäºè¿è¡æ¶å
ååºåï¼
**Java 8**
- The pc Registerï¼ç¨åºè®¡æ°å¨
- Java Virtual Machine Stacksï¼Java èææºæ
- Heapï¼å
- Method Areaï¼æ¹æ³åº
- Run-Time Constant Poolï¼è¿è¡æ¶å¸¸éæ±
- Native Method Stacksï¼æ¬å°æ¹æ³æ
### è¿è¡æ¶æ 帧å
å«åªäºç»æï¼
- å±é¨åé表
- æä½æ°æ
- å¨æè¿æ¥
- è¿åå°å
- éå ä¿¡æ¯
### JVM å¦ä½ç¡®å®åå¾å¯¹è±¡ï¼
JVM éç¨çæ¯å¯è¾¾æ§åæç®æ³ï¼éè¿ GC Roots æ¥å¤å®å¯¹è±¡æ¯å¦åæ´»ï¼ä» GC Roots åä¸è¿½æº¯ãæç´¢ï¼ä¼äº§ç Reference Chainãå½ä¸ä¸ªå¯¹è±¡ä¸è½åä»»ä½ä¸ä¸ª GC Root 产çå
³ç³»æ¶ï¼å°±å¤å®ä¸ºåå¾ã
软å¼ç¨åå¼±å¼ç¨ï¼ä¹ä¼å½±å对象çåæ¶ãå
åä¸è¶³æ¶ä¼åæ¶è½¯å¼ç¨å¯¹è±¡ï¼GC æ¶ä¼åæ¶å¼±å¼ç¨å¯¹è±¡ã
### åªäºæ¯ GC Rootsï¼
- å¨èææºæ ï¼æ 帧ä¸çæ¬å°åé表ï¼ä¸å¼ç¨ç对象ï¼è¬å¦å个线ç¨è¢«è°ç¨çæ¹æ³å æ ä¸ä½¿ç¨å°çåæ°ãå±é¨åéã临æ¶åéçã
- 卿¹æ³åºä¸ç±»éæå±æ§å¼ç¨ç对象ï¼è¬å¦Javaç±»çå¼ç¨ç±»åéæåéã
- 卿¹æ³åºä¸å¸¸éå¼ç¨ç对象ï¼è¬å¦åç¬¦ä¸²å¸¸éæ± ï¼String Tableï¼éçå¼ç¨ã
- 卿¬å°æ¹æ³æ ä¸JNIï¼å³é常æè¯´çNativeæ¹æ³ï¼å¼ç¨ç对象ã
- Javaèææºå
é¨çå¼ç¨ï¼å¦åºæ¬æ°æ®ç±»å对åºçClass对象ï¼ä¸äºå¸¸é©»çå¼å¸¸å¯¹è±¡ï¼æ¯å¦ NullPointExcepitonãOutOfMemoryErrorï¼çï¼è¿æç³»ç»ç±»å è½½å¨ã
- ææè¢«åæ¥éï¼synchronizedå
³é®åï¼ææç对象ã
- åæ Java èææºå
鍿
åµç JMXBeanãJVMTI䏿³¨åçåè°ãæ¬å°ä»£ç ç¼åçã
### å¦ä½å¼å¯åæ¥ç GC æ¥å¿ï¼
常è§ç GC æ¥å¿å¼å¯åæ°å
æ¬ï¼
`-Xloggc:filename`ï¼æå®æ¥å¿æä»¶è·¯å¾
`-XX:+PrintGC`ï¼æå° GC åºæ¬ä¿¡æ¯
`-XX:+PrintGCDetails`ï¼æå° GC 详ç»ä¿¡æ¯
`-XX:+PrintGCTimeStamps`ï¼æå° GC æ¶é´æ³
`-XX:+PrintGCDateStamps`ï¼æå° GC æ¥æä¸æ¶é´
`-XX:+PrintHeapAtGC`ï¼æå° GC ååçå ãæ¹æ³åºãå
空é´å¯ç¨å®¹éåå
`-XX:+PrintTenuringDistribution`ï¼æå°ç¬è¿æ¶éåå©ä½å¯¹è±¡çå¹´é¾åå¸ä¿¡æ¯ï¼æå©äº MaxTenuringThreshold åæ°è°ä¼è®¾ç½®
`-XX:+PrintAdaptiveSizePolicy`ï¼æå°æ¶éå¨èªå¨è®¾ç½®å 空é´åå代åºå大å°ãæ¶éç®æ çèªå¨è°èçç¸å
³ä¿¡æ¯
`-XX:+PrintGCApplicationConcurrentTime`ï¼æå° GC è¿ç¨ä¸ç¨æ·çº¿ç¨å¹¶åæ¶é´
`-XX:+PrintGCApplicationStoppedTime`ï¼æå° GC è¿ç¨ä¸ç¨æ·çº¿ç¨åé¡¿æ¶é´
`-XX:+HeapDumpOnOutOfMemoryError`ï¼å oom æ¶èªå¨ dump
`-XX:HeapDumpPath`ï¼å oom æ¶ dump æä»¶è·¯å¾
Java 9 JVM æ¥å¿æ¨¡åè¿è¡äºéæï¼åæ°æ ¼å¼åçååï¼è¿ä¸ªéè¦ç¥éã
GC æ¥å¿è¾åºçæ ¼å¼ï¼ä¼éçä¸é¢çåæ°ä¸åèåçååãå
³æ³¨å个å代çå
åä½¿ç¨æ
åµãåå¾åæ¶æ¬¡æ°ãåå¾åæ¶çåå ãåå¾åæ¶å ç¨çæ¶é´ãååéãç¨æ·çº¿ç¨åé¡¿æ¶é´ã
åå©å·¥å
·å¯è§åå·¥å
·å¯ä»¥æ´æ¹ä¾¿çåæï¼å¨çº¿å·¥å
· GCeasyï¼ç¦»çº¿çå¯ä»¥ä½¿ç¨ GCViewerã
妿ç°åºç¯å¢ä¸å
许ï¼å¯ä»¥ä½¿ç¨ JDK èªå¸¦ç jstat å·¥å
·çæ§è§å¯ GC æ
åµã
### 说ä¸ä¸åå¾å代æ¶éçè¿ç¨
å为æ°ç代åèå¹´ä»£ï¼æ°ç代é»è®¤å æ»ç©ºé´ç 1/3ï¼è年代é»è®¤å 2/3ã
æ°ç代使ç¨å¤å¶ç®æ³ï¼æ 3 个ååºï¼EdenãTo SurvivorãFrom Survivorï¼å®ä»¬çé»è®¤å æ¯æ¯ 8:1:1ã
彿°ç代ä¸ç Eden åºå
åä¸è¶³æ¶ï¼å°±ä¼è§¦å Minor GCï¼è¿ç¨å¦ä¸ï¼
- å¨ Eden åºæ§è¡äºç¬¬ä¸æ¬¡ GC ä¹åï¼åæ´»ç对象ä¼è¢«ç§»å¨å°å
¶ä¸ä¸ä¸ª Survivor ååºï¼
- Eden åºå次 GCï¼è¿æ¶ä¼éç¨å¤å¶ç®æ³ï¼å° Eden å from åºä¸èµ·æ¸
çï¼åæ´»ç对象ä¼è¢«å¤å¶å° to åºï¼
- ç§»å¨ä¸æ¬¡ï¼å¯¹è±¡å¹´é¾å 1ï¼å¯¹è±¡å¹´é¾å¤§äºä¸å®éå¼ä¼ç´æ¥ç§»å¨å°è年代
- Survivor åºç¸å年龿æå¯¹è±¡å¤§å°çæ»å > (Survivor åºå
åå¤§å° * è¿ä¸ªç®æ 使ç¨ç)æ¶ï¼å¤§äºæçäºè¯¥å¹´é¾çå¯¹è±¡ç´æ¥è¿å
¥è年代ãå
¶ä¸è¿ä¸ªä½¿ç¨çéè¿ -XX:TargetSurvivorRatio æå®ï¼é»è®¤ä¸º 50%
- Survivor åºå
åä¸è¶³ä¼åçæ
ä¿åé
- è¶
è¿æå®å¤§å°ç对象å¯ä»¥ç´æ¥è¿å
¥è年代
- Major GCï¼æçæ¯è年代çå徿¸
çï¼ä½å¹¶æªæ¾å°æç¡®è¯´æä½æ¶å¨è¿è¡Major GC
- FullGCï¼æ´ä¸ªå çå徿¶éï¼è§¦åæ¡ä»¶ï¼
1.æ¯æ¬¡æåå°è年代ç对象平å大å°>è年代å©ä½ç©ºé´
2.MinorGCååæ´»ç对象è¶
è¿äºè年代å©ä½ç©ºé´
3.å
空é´ä¸è¶³
4.System.gc() å¯è½ä¼å¼èµ·
5.CMS GCå¼å¸¸ï¼promotion failed:MinorGCæ¶ï¼survivorç©ºé´æ¾ä¸ä¸ï¼å¯¹è±¡åªè½æ¾å
¥è年代ï¼èè年代乿¾ä¸ä¸é æï¼concurrent mode failure:GCæ¶ï¼åæ¶æå¯¹è±¡è¦æ¾å
¥è年代ï¼èè年代空é´ä¸è¶³é æ
6.å å
ååé
å¾å¤§ç对象
### å¦ä½æ¾å°æ»éç线ç¨ï¼
æ»éç线ç¨å¯ä»¥ä½¿ç¨ jstack æä»¤ dump åº JVM ç线ç¨ä¿¡æ¯ã
jstack -l \ > threads.txt
ææ¶åéè¦dumpåºç°å¼å¸¸ï¼å¯ä»¥å ä¸ -F æä»¤ï¼å¼ºå¶å¯¼åº
jstack -F -l \ > threads.txt
妿å卿»éï¼ä¸è¬å¨æä»¶æåä¼æç¤ºæ¾å° deadlock çæ°éä¸çº¿ç¨ä¿¡æ¯
### invokedynamic æä»¤æ¯å¹²ä»ä¹çï¼
Java 7 å¼å§ï¼æ°å¼å
¥çåèç æä»¤ï¼å¯ä»¥å®ç°ä¸äºå¨æç±»åè¯è¨çåè½ãJava 8 ç Lambda 表达å¼å°±æ¯éè¿ invokedynamic æä»¤å®ç°ï¼ä½¿ç¨æ¹æ³å¥æå®ç°ã
### ä»ä¹æ¯éé¸åæï¼
åæå¯¹è±¡å¨æä½ç¨å
- å½ä¸ä¸ªå¯¹è±¡å¨æ¹æ³éé¢è¢«å®ä¹åï¼å®å¯è½è¢«å¤é¨æ¹æ³æå¼ç¨ï¼ä¾å¦ä½ä¸ºè°ç¨åæ°ä¼ éå°å
¶ä»æ¹æ³ä¸ï¼è¿ç§ç§°ä¸ºæ¹æ³éé¸ï¼
- 被å¤é¨çº¿ç¨è®¿é®å°ï¼è¬å¦èµå¼ç»å¯ä»¥å¨å
¶ä»çº¿ç¨ä¸è®¿é®çå®ä¾åéï¼è¿ç§ç§°ä¸ºçº¿ç¨éé¸ï¼
- ä»ä¸éé¸
妿è½è¯æä¸ä¸ªå¯¹è±¡ä¸ä¼éé¸å°æ¹æ³æçº¿ç¨ä¹å¤ï¼æè
éé¸ç¨åº¦æ¯è¾ä½ï¼åªéé¸åºæ¹æ³èä¸ä¼éé¸åºçº¿ç¨ï¼ï¼åå¯è½ä¸ºè¿ä¸ªå¯¹è±¡å®ä¾éåä¸åç¨åº¦çä¼åï¼å¦æ ä¸åé
ãæ éæ¿æ¢ã忥æ¶é¤ã
### ä»ä¹æ¯æ¹æ³å
èï¼
为äºåå°æ¹æ³è°ç¨çå¼éï¼å¯ä»¥æä¸äºçå°çæ¹æ³ï¼çº³å
¥å°ç®æ æ¹æ³çè°ç¨èå´ä¹å
ï¼è¿æ ·å°±å°äºä¸æ¬¡æ¹æ³è°ç¨ï¼æåé度
### JVM çæ§ä¸åæå·¥å
·ä½ ç¨è¿åªäºï¼ä»ç»ä¸ä¸ã
`jps`ï¼æ¾ç¤ºç³»ç»ææèææºè¿ç¨ä¿¡æ¯çå½ä»¤è¡å·¥å
·
`jstat`ï¼çè§åæèææºè¿è¡ç¶æçå½ä»¤è¡å·¥å
·
`jinfo`ï¼æ¥çåè°æ´èææºåæ°çå½ä»¤è¡å·¥å
·
`jmap`ï¼çæèææºå å
å转å¨å¿«ç
§çå½ä»¤è¡å·¥å
·
`jhat`ï¼æ¾ç¤ºååæèææºç转å¨å¿«ç
§æä»¶çå½ä»¤è¡å·¥å
·
`jstack`ï¼çæèææºç线ç¨å¿«ç
§çå½ä»¤è¡å·¥å
·
`jcmd`ï¼èææºè¯æå·¥å
·ï¼JDK 7 æä¾
`jhsdb`ï¼åºäºæå¡æ§ä»£çå®ç°çè¿ç¨å¤å¯è§åè°è¯å·¥å
·ï¼JDK 9 æä¾
`JConsole`ï¼åºäºJMXçå¯è§åçè§å管çå·¥å
·
`jvisualvm`ï¼å¾å½¢åèææºä½¿ç¨æ
åµçåæå·¥å
·
`Java Mission Control`ï¼çæ§å管ç Java åºç¨ç¨åºçå·¥å
·
`MAT`ï¼Memory Analyzer Toolï¼èææºå
ååæå·¥å
·
`vjtools`ï¼å¯åä¼çå
嫿 ¸å¿ç±»åºä¸é®é¢åæå·¥å
·
`arthas`ï¼é¿é弿ºç Java è¯æå·¥å
·
`greys`ï¼JVMè¿ç¨æ§è¡è¿ç¨ä¸çå¼å¸¸è¯æå·¥å
·
`GCHisto`ï¼GC åæå·¥å
·
`GCViewer`ï¼GC æ¥å¿æä»¶åæå·¥å
·
`GCeasy`ï¼å¨çº¿ç GC æ¥å¿æä»¶åæå·¥å
·
`JProfiler`ï¼æ£æ¥ãçæ§ã追踪 Java æ§è½çå·¥å
·
`BTrace`ï¼åºäºå¨æåèç ä¿®æ¹ææ¯(Hotswap)å®ç°çJavaç¨åºè¿½è¸ªä¸åæå·¥å
·
ä¸é¢å¯ä»¥éç¹ä½éªä¸ï¼
JDK èªå¸¦çå½ä»¤è¡å·¥å
·æ¹ä¾¿å¿«æ·ï¼ä¸æ¯ç¹å«å¤æçé®é¢å¯ä»¥å¿«éå®ä½ï¼
é¿éç arthas å½ä»¤è¡ä¹ä¸éï¼
å¯è§åå·¥å
· MATãJProfiler æ¯è¾å¼ºå¤§ã
### æè¿°ä¸ä¸ä»ä¹æ
åµä¸ï¼å¯¹è±¡ä¼ä»å¹´è½»ä»£è¿å
¥è年代
- 对象çå¹´é¾è¶
è¿ä¸å®éå¼ï¼-XX:MaxTenuringThreshold å¯ä»¥æå®è¯¥éå¼
- å¨æå¯¹è±¡å¹´é¾å¤å®ï¼æçåå¾åæ¶ç®æ³ï¼æ¯å¦ G1ï¼å¹¶ä¸è¦æ± age å¿
é¡»è¾¾å° 15 æè½æåå°è年代ï¼å®ä¼ä½¿ç¨ä¸äºå¨æçè®¡ç®æ¹æ³
- 大å°è¶
åºæä¸ªéå¼ç对象å°ç´æ¥å¨è年代ä¸åé
ï¼å¼é»è®¤ä¸º 0ï¼æææ¯å
¨é¨é¦é Eden åºè¿è¡åé
ï¼-XX:PretenureSizeThreshold å¯ä»¥æå®è¯¥éå¼ï¼é¨åæ¶éå¨ä¸æ¯æ
- åé
æ
ä¿ï¼å½ Survivor 空é´ä¸å¤çæ¶åï¼åéè¦ä¾èµå
¶ä»å
åï¼æè年代ï¼è¿è¡åé
æ
ä¿ï¼è¿ä¸ªæ¶åï¼å¯¹è±¡ä¹ä¼ç´æ¥å¨è年代ä¸åé
### å·¥ä½ä¸å¸¸ç¨ç JVM é
ç½®åæ°æåªäºï¼
Java 8 为ä¾
**æ¥å¿**
-XX:+PrintFlagsFinalï¼æå°JVMææåæ°çå¼
-XX:+PrintGCï¼æå°GCä¿¡æ¯
-XX:+PrintGCDetailsï¼æå°GC详ç»ä¿¡æ¯
-XX:+PrintGCTimeStampsï¼æå°GCçæ¶é´æ³
-Xloggc:filenameï¼è®¾ç½®GC logæä»¶çä½ç½®
-XX:+PrintTenuringDistributionï¼æ¥çç¬è¿æ¶éåå©ä½å¯¹è±¡çå¹´é¾åå¸ä¿¡æ¯
**å
å设置**
-Xmsï¼è®¾ç½®å çåå§åå
å大å°
-Xmxï¼è®¾ç½®å çæå¤§å
å
-Xmnï¼è®¾ç½®æ°ç代å
å大å°
-Xssï¼è®¾ç½®çº¿ç¨æ 大å°
-XX:NewRatioï¼æ°ç代ä¸è年代æ¯å¼
-XX:SurvivorRatioï¼æ°ç代ä¸Edenåºä¸ä¸¤ä¸ªSurvivoråºçæ¯å¼ï¼é»è®¤ä¸º8ï¼å³Eden:Survivor:Survivor=8:1:1
-XX:MaxTenuringThresholdï¼ä»å¹´è½»ä»£å°èå¹´ä»£ï¼æå¤§æåå¹´é¾ãCMS ä¸é»è®¤ä¸º 6ï¼G1 ä¸é»è®¤ä¸º 15
-XX:MetaspaceSizeï¼è®¾ç½®å
空é´ç大å°ï¼ç¬¬ä¸æ¬¡è¶
è¿å°è§¦å GC
-XX:MaxMetaspaceSizeï¼å
ç©ºé´æå¤§å¼
-XX:MaxDirectMemorySizeï¼ç¨äºè®¾ç½®ç´æ¥å
åçæå¤§å¼ï¼éå¶éè¿ DirectByteBuffer ç³è¯·çå
å
-XX:ReservedCodeCacheSizeï¼ç¨äºè®¾ç½® JIT ç¼è¯åç代ç åæ¾åºå¤§å°ï¼å¦æè§å¯å°è¿ä¸ªå¼æéå¶ï¼å¯ä»¥éå½è°å¤§ï¼ä¸è¬å¤ç¨å³å¯
**设置å徿¶éç¸å
³**
-XX:+UseSerialGCï¼è®¾ç½®ä¸²è¡æ¶éå¨
-XX:+UseParallelGCï¼è®¾ç½®å¹¶è¡æ¶éå¨
-XX:+UseConcMarkSweepGCï¼ä½¿ç¨CMSæ¶éå¨
-XX:ParallelGCThreadsï¼è®¾ç½®Parallel GCççº¿ç¨æ°
-XX:MaxGCPauseMillisï¼GCæå¤§æåæ¶é´ ms
-XX:+UseG1GCï¼ä½¿ç¨G1å徿¶éå¨
CMS åå¾åæ¶å¨ç¸å
³
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFractionï¼ä¸åè
é
å使ç¨ï¼æå®MajorGCçåçæ¶æº
-XX:+ExplicitGCInvokesConcurrentï¼ä»£ç è°ç¨ System.gc() å¼å§å¹¶è¡ FullGCï¼å»ºè®®å ä¸è¿ä¸ªåæ°
-XX:+CMSScavengeBeforeRemarkï¼è¡¨ç¤ºå¼å¯æå
³éå¨ CMS éæ°æ è®°é¶æ®µä¹åçæ¸
é¤ï¼YGCï¼å°è¯ï¼å®å¯ä»¥éä½ remark æ¶é´ï¼å»ºè®®å ä¸
-XX:+ParallelRefProcEnabledï¼å¯ä»¥ç¨æ¥å¹¶è¡å¤ç Referenceï¼ä»¥å å¿«å¤çé度ï¼ç¼©çèæ¶
**G1 åå¾åæ¶å¨ç¸å
³**
-XX:MaxGCPauseMillisï¼ç¨äºè®¾ç½®ç®æ åé¡¿æ¶é´ï¼G1 ä¼å°½åè¾¾æ
-XX:G1HeapRegionSizeï¼ç¨äºè®¾ç½®å°å åºå¤§å°ï¼å»ºè®®ä¿æé»è®¤
-XX:InitiatingHeapOccupancyPercentï¼è¡¨ç¤ºå½æ´ä¸ªå å
å使ç¨è¾¾å°ä¸å®æ¯ä¾ï¼é»è®¤æ¯ 45%ï¼ï¼å¹¶åæ è®°é¶æ®µå°±ä¼è¢«å¯å¨
-XX:ConcGCThreadsï¼è¡¨ç¤ºå¹¶åå徿¶éå¨ä½¿ç¨ççº¿ç¨æ°éï¼é»è®¤å¼é JVM è¿è¡çå¹³å°ä¸åèåå¨ï¼ä¸å»ºè®®ä¿®æ¹
åæ°æ¥è¯¢å®ç½å°åï¼
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
建议é¢è¯æ¶æå¥½è½è®°ä½ CMS å G1çåæ°ï¼ç¹ç¹çªåºä½¿ç¨è¾å¤ï¼è¢«é®çæ¦ç大
### JIT æ¯ä»ä¹ï¼
Just In Time Compiler çç®ç§°ï¼å³æ¶ç¼è¯å¨ãä¸ºäºæé«çç¹ä»£ç çæ§è¡æçï¼å¨è¿è¡æ¶ï¼èææºå°ä¼æè¿äºä»£ç ç¼è¯æä¸æ¬å°å¹³å°ç¸å
³çæºå¨ç ï¼å¹¶è¿è¡åç§å±æ¬¡çä¼åï¼å®æè¿ä¸ªä»»å¡çç¼è¯å¨å°±æ¯ JITã
### è°è°å¯¹ OOM ç认è¯
é¤äºç¨åºè®¡æ°å¨ï¼å
¶ä»å
ååºå齿 OOM çé£é©ã
- æ ä¸è¬ç»å¸¸ä¼åç StackOverflowErrorï¼æ¯å¦ 32 ä½ç windows ç³»ç»åè¿ç¨éå¶ 2G å
åï¼æ éå建线ç¨å°±ä¼åçæ ç OOM
- Java 8 叏鿱 ç§»å°å ä¸ï¼æº¢åºä¼åº java.lang.OutOfMemoryError: Java heap spaceï¼è®¾ç½®æå¤§å
空é´å¤§å°åæ°æ æ
- å å
åæº¢åºï¼æ¥éåä¸ï¼è¿ç§æ¯è¾å¥½çè§£ï¼GC ä¹åæ æ³å¨å ä¸ç³è¯·å
ååå»ºå¯¹è±¡å°±ä¼æ¥é
- æ¹æ³åº OOMï¼ç»å¸¸ä¼éå°çæ¯å¨æçæå¤§éçç±»ãjsp ç
- ç´æ¥å
å OOMï¼æ¶åå° -XX:MaxDirectMemorySize åæ°å Unsafe 对象对å
åçç³è¯·
### ä½ æåªäºææ®µæ¥ææ¥ OOM çé®é¢ï¼
- å¢å ä¸¤ä¸ªåæ° -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprofï¼å½ OOM åçæ¶èªå¨ dump å å
åä¿¡æ¯å°æå®ç®å½
- åæ¶ jstat æ¥ççæ§ JVM çå
åå GC æ
åµï¼å
è§å¯é®é¢å¤§æ¦åºå¨ä»ä¹åºå
- ä½¿ç¨ MAT å·¥å
·è½½å
¥å° dump æä»¶ï¼åæå¤§å¯¹è±¡çå ç¨æ
åµï¼æ¯å¦ HashMap åç¼åæªæ¸
çï¼æ¶é´é¿äºå°±ä¼å
åæº¢åºï¼å¯ä»¥ææ¹ä¸ºå¼±å¼ç¨
### ä»ä¹æ
åµåçæ æº¢åºï¼
-Xsså¯ä»¥è®¾ç½®çº¿ç¨æ ç大å°ï¼å½çº¿ç¨æ¹æ³éå½è°ç¨å±æ¬¡å¤ªæ·±æè
æ 帧ä¸çå±é¨åéè¿å¤æ¶ï¼ä¼åºç°æ 溢åºé误 java.lang.StackOverflowError
### éå°è¿å å¤å
åæº¢åºåï¼
Unsafe ç±»ç³è¯·å
åãJNI 对å
åè¿è¡æä½ãNetty è°ç¨æä½ç³»ç»ç malloc 彿°çç´æ¥å
åï¼è¿äºå
忝ä¸å JVM æ§å¶çï¼ä¸å éå¶ç使ç¨ï¼å¾å®¹æåçæº¢åºãè¿ç§æ
åµæä¸ªæ¾èç¹ç¹ï¼dump çå æä»¶ä¿¡æ¯æ£å¸¸çè³å¾å°ã
-XX:MaxDirectMemorySize å¯ä»¥æå®æå¤§ç´æ¥å
åï¼ä½éå¶ä¸ä½ææå å¤å
åç使ç¨ã
### éå°è¿å
ç©ºé´æº¢åºåï¼
å
空é´å¨æ¬å°å
åä¸ï¼é»è®¤æ¯æ²¡æä¸éçï¼ä¸å éå¶åºäºé®é¢ä¼å½±åæ´ä¸ªæå¡å¨çï¼æä»¥ä¹æ¯æ¯è¾å±é©çã-XX:MaxMetaspaceSize å¯ä»¥æå®æå¤§å¼ã
ä¸è¬ä½¿ç¨å¨æä»£ççæ¡æ¶ä¼çæå¾å¤ Java ç±»ï¼å¦æå ç¨ç©ºé´è¶
åºäºæä»¬çè®¾å®æå¤§å¼ï¼ä¼åçå
ç©ºé´æº¢åºã
### 被å¼ç¨ç对象就ä¸å®è½åæ´»åï¼
ä¸ä¸å®ï¼ç Reference ç±»åï¼å¼±å¼ç¨å¨ GC æ¶ä¼è¢«åæ¶ï¼è½¯å¼ç¨å¨å
åä¸è¶³çæ¶åï¼å³ OOM åä¼è¢«åæ¶ï¼ä½å¦ææ²¡æå¨ Reference Chain ä¸ç对象就ä¸å®ä¼è¢«åæ¶ã
### ä½ åè¿ JVM è°ä¼ï¼è¯´è¯´å¦ä½æ¥ç JVM åæ°é»è®¤å¼ï¼
- jps -v å¯ä»¥æ¥ç jvm è¿ç¨æ¾ç¤ºæå®çåæ°
- ä½¿ç¨ -XX:+PrintFlagsFinal å¯ä»¥çå° JVM ææåæ°çå¼
- jinfo å¯ä»¥å®æ¶æ¥çåè°æ´èææºå项忰
### ä»ä¹æ¯åèç ï¼éç¨åèç çæå¤§å¥½å¤æ¯ä»ä¹
* **åèç **ï¼Javaæºä»£ç ç»è¿èææºç¼è¯å¨ç¼è¯å产ççæä»¶ï¼å³æ©å±ä¸º.classçæä»¶ï¼ï¼å®ä¸é¢åä»»ä½ç¹å®çå¤çå¨ï¼åªé¢åèææºã
* **éç¨åèç ç好å¤**ï¼
Javaè¯è¨éè¿åèç çæ¹å¼ï¼å¨ä¸å®ç¨åº¦ä¸è§£å³äºä¼ ç»è§£éåè¯è¨æ§è¡æçä½çé®é¢ï¼åæ¶åä¿çäºè§£éåè¯è¨å¯ç§»æ¤çç¹ç¹ãæä»¥Javaç¨åºè¿è¡æ¶æ¯è¾é«æï¼èä¸ï¼ç±äºåèç å¹¶ä¸ä¸å¯¹ä¸ç§ç¹å®çæºå¨ï¼å æ¤ï¼Javaç¨åºæ 须鿰ç¼è¯ä¾¿å¯å¨å¤ç§ä¸åçè®¡ç®æºä¸è¿è¡ã
* **å
çä¸javaä¸çç¼è¯å¨åè§£éå¨**ï¼
Javaä¸å¼å
¥äºèææºçæ¦å¿µï¼å³å¨æºå¨åç¼è¯ç¨åºä¹é´å å
¥äºä¸å±æ½è±¡çèææºå¨ãè¿å°èæçæºå¨å¨ä»»ä½å¹³å°ä¸é½æä¾ç»ç¼è¯ç¨åºä¸ä¸ªçå
±åçæ¥å£ãç¼è¯ç¨åºåªéè¦é¢åèææºï¼çæèææºè½å¤çè§£ç代ç ï¼ç¶åç±è§£é卿¥å°èææºä»£ç 转æ¢ä¸ºç¹å®ç³»ç»çæºå¨ç æ§è¡ãå¨Javaä¸ï¼è¿ç§ä¾èææºçè§£ç代ç å«ååèç ï¼å³æ©å±ä¸º.classçæä»¶ï¼ï¼å®ä¸é¢åä»»ä½ç¹å®çå¤çå¨ï¼åªé¢åèææºãæ¯ä¸ç§å¹³å°çè§£é卿¯ä¸åçï¼ä½æ¯å®ç°çèææºæ¯ç¸åçãJavaæºç¨åºç»è¿ç¼è¯å¨ç¼è¯ååæåèç ï¼åèç ç±èææºè§£éæ§è¡ï¼èææºå°æ¯ä¸æ¡è¦æ§è¡çåèç éç»è§£éå¨ï¼è§£éå¨å°å
¶ç¿»è¯æç¹å®æºå¨ä¸çæºå¨ç ï¼ç¶åå¨ç¹å®çæºå¨ä¸è¿è¡ï¼è¿å°±æ¯ä¸é¢æå°çJavaçç¹ç¹çç¼è¯ä¸è§£éå¹¶åçè§£éã
Javaæºä»£ç ---->ç¼è¯å¨---->jvm坿§è¡çJavaåèç (å³èææä»¤)---->jvm---->jvmä¸è§£éå¨----->æºå¨å¯æ§è¡çäºè¿å¶æºå¨ç ---->ç¨åºè¿è¡ã
### ä»ä¹æ
åµä¸ä¼åçæ å
åæº¢åºã
**æè·¯ï¼** æè¿°æ å®ä¹ï¼åæè¿°ä¸ºä»ä¹ä¼æº¢åºï¼å说æä¸ä¸ç¸å
³é
ç½®åæ°ï¼OKçè¯å¯ä»¥ç»é¢è¯å®æåæ¯ä¸ä¸ªæ 溢åºçdemoã
**æççæ¡ï¼**
* æ æ¯çº¿ç¨ç§æçï¼ä»ççå½å¨æä¸çº¿ç¨ç¸åï¼æ¯ä¸ªæ¹æ³å¨æ§è¡çæ¶åé½ä¼å建ä¸ä¸ªæ 帧ï¼ç¨æ¥åå¨å±é¨åéè¡¨ï¼æä½æ°æ ï¼å¨æé¾æ¥ï¼æ¹æ³åºå£çä¿¡æ¯ãå±é¨åé表åå
å«åºæ¬æ°æ®ç±»åï¼å¯¹è±¡å¼ç¨ç±»å
* å¦æçº¿ç¨è¯·æ±çæ æ·±åº¦å¤§äºèææºæå
许çæå¤§æ·±åº¦ï¼å°æåºStackOverflowErrorå¼å¸¸ï¼æ¹æ³éå½è°ç¨äº§çè¿ç§ç»æã
* 妿Javaèææºæ å¯ä»¥å¨ææ©å±ï¼å¹¶ä¸æ©å±çå¨ä½å·²ç»å°è¯è¿ï¼ä½æ¯æ æ³ç³è¯·å°è¶³å¤çå
åå»å®ææ©å±ï¼æè
卿°å»ºç«çº¿ç¨çæ¶å没æè¶³å¤çå
åå»å建对åºçèææºæ ï¼é£ä¹Javaèææºå°æåºä¸ä¸ªOutOfMemory å¼å¸¸ã(线ç¨å¯å¨è¿å¤)
* åæ° -Xss å»è°æ´JVMæ ç大å°
### 详解JVMå
忍¡å
**æè·¯ï¼** ç»é¢è¯å®ç»ä¸ä¸JVMå
忍¡åå¾ï¼å¹¶æè¿°æ¯ä¸ªæ¨¡åçå®ä¹ï¼ä½ç¨ï¼ä»¥åå¯è½ä¼åå¨çé®é¢ï¼å¦æ 溢åºçã
**æççæ¡ï¼**
* JVMå
åç»æ

ç¨åºè®¡æ°å¨ï¼å½åçº¿ç¨ææ§è¡çåèç çè¡å·æç¤ºå¨ï¼ç¨äºè®°å½æ£å¨æ§è¡çèææºåèæä»¤å°åï¼çº¿ç¨ç§æã
Javaèææ ï¼åæ¾åºæ¬æ°æ®ç±»åã对象çå¼ç¨ãæ¹æ³åºå£çï¼çº¿ç¨ç§æã
Nativeæ¹æ³æ ï¼åèææ ç¸ä¼¼ï¼åªä¸è¿å®æå¡äºNativeæ¹æ³ï¼çº¿ç¨ç§æã
Javaå ï¼javaå
åæå¤§çä¸åï¼ææå¯¹è±¡å®ä¾ãæ°ç»é½åæ¾å¨javaå ï¼GCåæ¶çå°æ¹ï¼çº¿ç¨å
±äº«ã
æ¹æ³åºï¼åæ¾å·²è¢«å è½½ç类信æ¯ã常éãéæåéã峿¶ç¼è¯å¨ç¼è¯åçä»£ç æ°æ®çãï¼å³æ°¸ä¹
带ï¼ï¼åæ¶ç®æ ä¸»è¦æ¯å¸¸éæ± çåæ¶åç±»åçå¸è½½ï¼å线ç¨å
񄧮
### JVMå
å为ä»ä¹è¦åææ°ç代ï¼èå¹´ä»£ï¼æä¹
ä»£ãæ°ç代ä¸ä¸ºä»ä¹è¦å为EdenåSurvivorã
**æè·¯ï¼** å
讲ä¸ä¸JAVAå ï¼æ°ç代çååï¼åè°è°å®ä»¬ä¹é´ç转åï¼ç¸äºä¹é´ä¸äºåæ°çé
ç½®ï¼å¦ï¼ âXX:NewRatioï¼âXX:SurvivorRatioçï¼ï¼åè§£é为ä»ä¹è¦è¿æ ·ååï¼æå¥½å ä¸ç¹èªå·±ççè§£ã
**æççæ¡ï¼**
**1ï¼å
±äº«å
ååºåå**
* å
±äº«å
ååº = æä¹
带 + å
* æä¹
带 = æ¹æ³åº + å
¶ä»
* Javaå = è年代 + æ°ç代
* æ°ç代 = Eden + S0 + S1
**2ï¼ä¸äºåæ°çé
ç½®**
* é»è®¤çï¼æ°ç代 ( Young ) ä¸è年代 ( Old ) çæ¯ä¾çå¼ä¸º 1:2 ï¼å¯ä»¥éè¿åæ° âXX:NewRatio é
ç½®ã
* é»è®¤çï¼Edem : from : to = 8 : 1 : 1 ( å¯ä»¥éè¿åæ° âXX:SurvivorRatio æ¥è®¾å®)
* Survivoråºä¸ç对象被å¤å¶æ¬¡æ°ä¸º15(对åºèææºåæ° -XX:+MaxTenuringThreshold)
**3)为ä»ä¹è¦å为EdenåSurvivor?为ä»ä¹è¦è®¾ç½®ä¸¤ä¸ªSurvivoråºï¼**
* å¦ææ²¡æSurvivorï¼Edenåºæ¯è¿è¡ä¸æ¬¡Minor GCï¼åæ´»ç对象就ä¼è¢«éå°è年代ãè年代å¾å¿«è¢«å¡«æ»¡ï¼è§¦åMajor GC.è年代çå
å空é´è¿å¤§äºæ°ç代ï¼è¿è¡ä¸æ¬¡Full GCæ¶èçæ¶é´æ¯Minor GCé¿å¾å¤,æä»¥éè¦å为EdenåSurvivorã
* Survivorçå卿ä¹ï¼å°±æ¯åå°è¢«éå°è年代ç对象ï¼è¿èåå°Full GCçåçï¼Survivorçé¢çéä¿è¯ï¼åªæç»å16次Minor GCè¿è½å¨æ°ç代ä¸åæ´»çå¯¹è±¡ï¼æä¼è¢«éå°è年代ã
* 设置两个Survivoråºæå¤§ç好å¤å°±æ¯è§£å³äºç¢çåï¼ååæ°å»ºç对象å¨Edenä¸ï¼ç»å䏿¬¡Minor GCï¼Edenä¸çåæ´»å¯¹è±¡å°±ä¼è¢«ç§»å¨å°ç¬¬ä¸åsurvivor space S0ï¼Eden被æ¸
空ï¼çEdenåºå满äºï¼å°±å触å䏿¬¡Minor GCï¼EdenåS0ä¸çåæ´»å¯¹è±¡åä¼è¢«å¤å¶éå
¥ç¬¬äºåsurvivor space S1ï¼è¿ä¸ªè¿ç¨é常éè¦ï¼å 为è¿ç§å¤å¶ç®æ³ä¿è¯äºS1䏿¥èªS0åEden两é¨åçåæ´»å¯¹è±¡å ç¨è¿ç»çå
å空é´ï¼é¿å
äºç¢çåçåçï¼
### JVMä¸ä¸æ¬¡å®æ´çGCæµç¨æ¯ææ ·çï¼å¯¹è±¡å¦ä½æåå°è年代
**æè·¯ï¼** å
æè¿°ä¸ä¸Javaå å
åååï¼åè§£éMinor GCï¼Major GCï¼full GCï¼æè¿°å®ä»¬ä¹é´è½¬åæµç¨ã
**æççæ¡ï¼**
* Javaå = è年代 + æ°ç代
* æ°ç代 = Eden + S0 + S1
* å½ Eden åºçç©ºé´æ»¡äºï¼ Javaèææºä¼è§¦å䏿¬¡ Minor GCï¼ä»¥æ¶éæ°ç代çåå¾ï¼åæ´»ä¸æ¥ç对象ï¼åä¼è½¬ç§»å° Survivoråºã
* **大对象**ï¼éè¦å¤§éè¿ç»å
å空é´çJava对象ï¼å¦é£ç§å¾é¿çå符串ï¼**ç´æ¥è¿å
¥èå¹´æ**ï¼
* å¦æå¯¹è±¡å¨Edenåºçï¼å¹¶ç»è¿ç¬¬ä¸æ¬¡Minor GCåä»ç¶åæ´»ï¼å¹¶ä¸è¢«Survivor容纳çè¯ï¼å¹´é¾è®¾ä¸º1ï¼æ¯ç¬è¿ä¸æ¬¡Minor GCï¼å¹´é¾+1ï¼**è¥å¹´é¾è¶
è¿ä¸å®éå¶ï¼15ï¼ï¼å被æåå°èå¹´æ**ãå³**é¿æåæ´»ç对象è¿å
¥èå¹´æ**ã
* è年代满äºè**æ æ³å®¹çº³æ´å¤ç对象** ï¼Minor GC ä¹åé常就ä¼è¿è¡Full GCï¼Full GC æ¸
çæ´ä¸ªå
åå â **å
æ¬å¹´è½»ä»£åå¹´è代**ã
* Major GC **åçå¨è年代çGC** ï¼**æ¸
çèå¹´åº**ï¼ç»å¸¸ä¼ä¼´éè³å°ä¸æ¬¡Minor GCï¼**æ¯Minor GCæ
¢10å以ä¸**ã
### ä½ ç¥éåªå ç§å徿¶éå¨ï¼åèªçä¼ç¼ºç¹ï¼éç¹è®²ä¸cmsåG1ï¼å
æ¬åçï¼æµç¨ï¼ä¼ç¼ºç¹ã
**æè·¯ï¼** ä¸å®è¦è®°ä½å
¸åçå徿¶éå¨ï¼å°¤å
¶cmsåG1ï¼å®ä»¬çåçä¸åºå«ï¼æ¶åçåå¾åæ¶ç®æ³ã
**æççæ¡ï¼**
**1ï¼å ç§å徿¶éå¨ï¼**
* **Serialæ¶éå¨ï¼** å线ç¨çæ¶éå¨ï¼æ¶éå徿¶ï¼å¿
é¡»stop the worldï¼ä½¿ç¨å¤å¶ç®æ³ã
* **ParNewæ¶éå¨ï¼** Serialæ¶éå¨çå¤çº¿ç¨çæ¬ï¼ä¹éè¦stop the worldï¼å¤å¶ç®æ³ã
* **Parallel Scavengeæ¶éå¨ï¼** æ°ç代æ¶éå¨ï¼å¤å¶ç®æ³çæ¶éå¨ï¼å¹¶åçå¤çº¿ç¨æ¶éå¨ï¼ç®æ æ¯è¾¾å°ä¸ä¸ªå¯æ§çååéãå¦æèææºæ»å
±è¿è¡100åéï¼å
¶ä¸åå¾è±æ1åéï¼ååéå°±æ¯99%ã
* **Serial Oldæ¶éå¨ï¼** æ¯Serialæ¶éå¨çèå¹´ä»£çæ¬ï¼åçº¿ç¨æ¶éå¨ï¼ä½¿ç¨æ è®°æ´çç®æ³ã
* **Parallel Oldæ¶éå¨ï¼** æ¯Parallel Scavengeæ¶éå¨çèå¹´ä»£çæ¬ï¼ä½¿ç¨å¤çº¿ç¨ï¼æ è®°-æ´çç®æ³ã
* **CMS(Concurrent Mark Sweep) æ¶éå¨ï¼** æ¯ä¸ç§ä»¥è·å¾æçåæ¶åé¡¿æ¶é´ä¸ºç®æ çæ¶éå¨ï¼**æ è®°æ¸
é¤ç®æ³ï¼è¿ä½è¿ç¨ï¼åå§æ è®°ï¼å¹¶åæ è®°ï¼éæ°æ è®°ï¼å¹¶åæ¸
é¤**ï¼æ¶éç»æä¼äº§ç大é空é´ç¢çã
* **G1æ¶éå¨ï¼** æ è®°æ´çç®æ³å®ç°ï¼**è¿ä½æµç¨ä¸»è¦å
æ¬ä»¥ä¸ï¼åå§æ è®°ï¼å¹¶åæ è®°ï¼æç»æ è®°ï¼çéæ è®°**ãä¸ä¼äº§ç空é´ç¢çï¼å¯ä»¥ç²¾ç¡®å°æ§å¶åé¡¿ã
**2ï¼CMSæ¶éå¨åG1æ¶éå¨çåºå«ï¼**
* CMSæ¶é卿¯èå¹´ä»£çæ¶éå¨ï¼å¯ä»¥é
åæ°ç代çSerialåParNewæ¶éå¨ä¸èµ·ä½¿ç¨ï¼
* G1æ¶é卿¶éèå´æ¯è年代忰ç代ï¼ä¸éè¦ç»åå
¶ä»æ¶éå¨ä½¿ç¨ï¼
* CMSæ¶éå¨ä»¥æå°çåé¡¿æ¶é´ä¸ºç®æ çæ¶éå¨ï¼
* G1æ¶éå¨å¯é¢æµåå¾åæ¶çåé¡¿æ¶é´
* CMSæ¶é卿¯ä½¿ç¨âæ è®°-æ¸
é¤âç®æ³è¿è¡çåå¾åæ¶ï¼å®¹æäº§çå
åç¢ç
* G1æ¶éå¨ä½¿ç¨çæ¯âæ è®°-æ´çâç®æ³ï¼è¿è¡äºç©ºé´æ´åï¼éä½äºå
å空é´ç¢çã
### å¦ä½æ¥ç JVM å½å使ç¨çæ¯ä»ä¹å徿¶éå¨ï¼
-XX:+PrintCommandLineFlags åæ°å¯ä»¥æå°åºæéå徿¶éå¨åå 空é´å¤§å°ç设置
妿å¼å¯äº GC æ¥å¿è¯¦ç»ä¿¡æ¯ï¼éé¢ä¹ä¼å
å«å代使ç¨çå徿¶éå¨çç®ç§°
### JVMå
忍¡åçç¸å
³ç¥è¯äºè§£å¤å°ï¼æ¯å¦éæåºï¼å
åå±éï¼happen-beforeï¼ä¸»å
åï¼å·¥ä½å
åã
**æè·¯ï¼** å
ç»åºJavaå
忍¡åå¾ï¼ç»åä¾åvolatile ï¼è¯´æä»ä¹æ¯éæåºï¼å
åå±éï¼æå¥½è½ç»é¢è¯å®å以ä¸demo说æã
**æççæ¡ï¼**
**1ï¼Javaå
忍¡åå¾ï¼**

Javaå
忍¡åè§å®äºææç**åéé½åå¨å¨ä¸»å
å**ä¸ï¼æ¯æ¡**线ç¨è¿æèªå·±çå·¥ä½å
å**ï¼çº¿ç¨çå·¥ä½å
åä¸ä¿åäºè¯¥çº¿ç¨ä¸æ¯ç¨å°çåéç主å
å坿¬æ·è´ï¼**线ç¨å¯¹åéçæææä½é½å¿
é¡»å¨å·¥ä½å
åä¸**è¿è¡ï¼**èä¸è½ç´æ¥è¯»å主å
å**ãä¸åç线ç¨ä¹é´ä¹**æ æ³ç´æ¥è®¿é®å¯¹æ¹å·¥ä½å
åä¸çåé**ï¼çº¿ç¨é´åéçä¼ éåéè¦èªå·±çå·¥ä½å
åå主åä¹é´è¿è¡æ°æ®åæ¥è¿è¡ã
**2ï¼æä»¤éæåºã**
å¨è¿éï¼å
ç䏿®µä»£ç
```
public class PossibleReordering {
static int x = 0, y = 0;
static int a = 0, b = 0;
public static void main(String[] args) throws InterruptedException {
Thread one = new Thread(new Runnable() { public void run() { a = 1; x = b; } });
Thread other = new Thread(new Runnable() { public void run() { b = 1; y = a; } }); one.start();other.start(); one.join();other.join(); System.out.println(â(â + x + â,â + y + â)â);}
```
è¿è¡ç»æå¯è½ä¸º(1,0)ã(0,1)æ(1,1)ï¼ä¹å¯è½æ¯(0,0)ãå 为ï¼å¨å®é
è¿è¡æ¶ï¼ä»£ç æä»¤å¯è½å¹¶ä¸æ¯ä¸¥æ ¼æç
§ä»£ç è¯å¥é¡ºåºæ§è¡çã大夿°ç°ä»£å¾®å¤çå¨é½ä¼éç¨å°æä»¤ä¹±åºæ§è¡ï¼out-of-order executionï¼ç®ç§°OoOEæOOEï¼çæ¹æ³ï¼å¨æ¡ä»¶å
许çæ
åµä¸ï¼ç´æ¥è¿è¡å½åæè½åç«å³æ§è¡çåç»æä»¤ï¼é¿å¼è·åä¸ä¸æ¡æä»¤æéæ°æ®æ¶é æççå¾
3ãéè¿ä¹±åºæ§è¡çææ¯ï¼å¤çå¨å¯ä»¥å¤§å¤§æé«æ§è¡æçãèè¿å°±æ¯**æä»¤éæ**ã
**3ï¼å
åå±é**
**å
åå±é**ï¼ä¹å«å
åæ
æ ï¼æ¯ä¸ç§CPUæä»¤ï¼ç¨äºæ§å¶ç¹å®æ¡ä»¶ä¸çéæåºåå
åå¯è§æ§é®é¢ã
* **LoadLoadå±é** ï¼å¯¹äºè¿æ ·çè¯å¥Load1; LoadLoad; Load2ï¼å¨Load2ååç»è¯»åæä½è¦è¯»åçæ°æ®è¢«è®¿é®åï¼ä¿è¯Load1è¦è¯»åçæ°æ®è¢«è¯»å宿¯ã
* **StoreStoreå±é** ï¼å¯¹äºè¿æ ·çè¯å¥Store1; StoreStore; Store2ï¼å¨Store2ååç»åå
¥æä½æ§è¡åï¼ä¿è¯Store1çåå
¥æä½å¯¹å
¶å®å¤çå¨å¯è§ã
* **LoadStoreå±é** ï¼å¯¹äºè¿æ ·çè¯å¥Load1; LoadStore; Store2ï¼å¨Store2ååç»åå
¥æä½è¢«å·åºåï¼ä¿è¯Load1è¦è¯»åçæ°æ®è¢«è¯»å宿¯ã
* **StoreLoadå±é** ï¼å¯¹äºè¿æ ·çè¯å¥Store1; StoreLoad; Load2ï¼å¨Load2ååç»ææè¯»åæä½æ§è¡åï¼ä¿è¯Store1çåå
¥å¯¹ææå¤çå¨å¯è§ãå®çå¼éæ¯åç§å±é䏿大çã å¨å¤§å¤æ°å¤çå¨çå®ç°ä¸ï¼è¿ä¸ªå±éæ¯ä¸ªä¸è½å±éï¼å
¼å
·å
¶å®ä¸ç§å
åå±éçåè½ã
**4ï¼happen-beforeåå**
* **å线ç¨happen-beforeåå**ï¼å¨åä¸ä¸ªçº¿ç¨ä¸ï¼ä¹¦åå¨åé¢çæä½happen-beforeåé¢çæä½ã éçhappen-beforeååï¼åä¸ä¸ªéçunlockæä½happen-beforeæ¤éçlockæä½ã
* **volatileçhappen-beforeåå**ï¼å¯¹ä¸ä¸ªvolatileåéçåæä½happen-before对æ¤åéçä»»ææä½(å½ç¶ä¹å
æ¬åæä½äº)ã
* **happen-beforeçä¼ éæ§åå**ï¼å¦æAæä½ happen-before Bæä½ï¼Bæä½happen-before Cæä½ï¼é£ä¹Aæä½happen-before Cæä½ã
* **线ç¨å¯å¨çhappen-beforeåå**ï¼åä¸ä¸ªçº¿ç¨çstartæ¹æ³happen-beforeæ¤çº¿ç¨çå
¶å®æ¹æ³ã
* **线ç¨ä¸æçhappen-beforeåå** ï¼å¯¹çº¿ç¨interruptæ¹æ³çè°ç¨happen-beforeè¢«ä¸æçº¿ç¨çæ£æµå°ä¸æåéç代ç ã
* **线ç¨ç»ç»çhappen-beforeååï¼** 线ç¨ä¸çæææä½é½happen-before线ç¨çç»æ¢æ£æµã
* **对象å建çhappen-beforeååï¼** ä¸ä¸ªå¯¹è±¡çåå§å宿å
äºä»çfinalizeæ¹æ³è°ç¨ã
### è°è°ä½ ç¥éçåå¾åæ¶ç®æ³
å¤æå¯¹è±¡æ¯å¦å¯åæ¶çç®æ³æä¸¤ç§ï¼
- **Reference Counting GCï¼å¼ç¨è®¡æ°ç®æ³**
- **Tracing GCï¼å¯è¾¾æ§åæç®æ³**
JVM ååååºæ¬é½æ¯ç¨ç Tracing GC å®ç°
大é¨åå徿¶éå¨éµä»äºå代æ¶é(Generational Collection)ç论ã
é对æ°ç代ä¸è年代忶åå¾å
åçç¹ç¹ï¼æåºäº 3 ç§ä¸åçç®æ³ï¼
**1ãæ è®°-æ¸
é¤ç®æ³(Mark-Sweep)**
æ è®°éåæ¶å¯¹è±¡ï¼ç»ä¸åæ¶ï¼ææ è®°åæ´»å¯¹è±¡ï¼åæ¶æªæ 记对象ã
缺ç¹ï¼
- 大é对象éè¦æ è®°ä¸æ¸
餿¶ï¼æçä¸é«
- æ è®°ãæ¸
é¤äº§çç大éä¸è¿ç»å
åç¢çï¼å¯¼è´æ æ³åé
大对象
**2ãæ è®°-å¤å¶ç®æ³(Mark-Copy)**
å¯ç¨å
åçå两åï¼ä½¿ç¨å
¶ä¸ä¸å Aï¼ç¨å®å°åæ´»ç对象å¤å¶å°å¦å¤ä¸å Bï¼ä¸æ¬¡æ§æ¸
空 Aï¼ç¶åæ¹åé
æ°å¯¹è±¡å° Bï¼å¦æ¤å¾ªç¯ã
缺ç¹ï¼
- ä¸éå大é对象ä¸å¯åæ¶çæ
åµï¼æ¢å¥è¯è¯´å°±æ¯ä»
éå大é对象å¯åæ¶ï¼å°é对象éå¤å¶çåºå
- åªè½ä½¿ç¨å
å容éçä¸åï¼æµªè´¹è¾å¤å
å空é´
**3ãæ è®°-æ´çç®æ³(Mark-Compact)**
æ è®°åæ´»ç对象ï¼ç»ä¸ç§»å°å
ååºåçä¸è¾¹ï¼æ¸
空å ç¨å
åè¾¹ç以å¤çå
åã
缺ç¹ï¼
- ç§»å¨å¤§éåæ´»å¯¹è±¡å¹¶æ´æ°å¼ç¨ï¼éæåç¨åºè¿è¡
### è°è°ä½ ç¥éçå徿¶éå¨
**Serial**
ç¹ç¹ï¼
- JDK 1.3 å¼å§æä¾
- æ°ç代æ¶éå¨
- æ 线ç¨äº¤äºå¼éï¼åçº¿ç¨æ¶éæçæé«
- è¿è¡å徿¶éæ¶éè¦æåç¨æ·çº¿ç¨
- éç¨äºå®¢æ·ç«¯ï¼å°å
åå çåæ¶
**ParNew**
ç¹ç¹ï¼
- æ¯ Serial æ¶éå¨çå¤çº¿ç¨å¹¶è¡ç
- JDK 7 ä¹åé¦éçæ°ç代æ¶éå¨
- ç¬¬ä¸æ¬¾æ¯æå¹¶åçæ¶éå¨ï¼é¦æ¬¡å®ç°å徿¶é线ç¨ä¸ç¨æ·çº¿ç¨åºæ¬ä¸åæ¶å·¥ä½
- é¤ Serial å¤ï¼åªæå®è½ä¸ CMS é
å
**Parallel Scavenge**
ç¹ç¹ï¼
- æ°ç代æ¶éå¨
- æ è®°-å¤å¶ç®æ³
- å¤çº¿ç¨å¹¶è¡æ¶éå¨
- 追æ±é«ååéï¼å³æå°çå徿¶éæ¶é´
- å¯ä»¥é
ç½®æå¤§åé¡¿æ¶é´ãå徿¶éæ¶é´å æ¯
- æ¯æå¼å¯å徿¶éèªéåºè°èçç¥ï¼è¿½æ±éåçåé¡¿æ¶é´ææå¤§çååé
**Serial Old**
ç¹ç¹ï¼
- ä¸ Serial ç±»ä¼¼ï¼æ¯ Serial æ¶éå¨çèå¹´ä»£çæ¬
- ä½¿ç¨æ è®°-æ´çç®æ³
**Parallel Old**
ç¹ç¹ï¼
- JDK 6 å¼å§æä¾
- Parallel Scavenge çè年代ç
- æ¯æå¤çº¿ç¨å¹¶åæ¶é
- æ è®°-æ´çç®æ³
- Parallel Scavenge + Parallel Old æ¯ä¸ä¸ªè¿½æ±é«ååéçç»å
**CMS**
ç¹ç¹ï¼
- æ è®°-æ¸
é¤ç®æ³
- è¿½æ±æçåæ¶åé¡¿æ¶é´
- å¤åºç¨äºå
³æ³¨ååºæ¶é´ç B/S æ¶æçæå¡ç«¯
- å¹¶åæ¶éãä½åé¡¿
- å ç¨ä¸é¨å线ç¨èµæºï¼åºç¨ç¨åºåæ
¢ï¼ååéä¸é
- æ æ³å¤çæµ®å¨åå¾ï¼å¯è½å¯¼è´ Full GC
- å
åç¢çåé®é¢
**G1**
ç¹ç¹ï¼
- JDK 6 å¼å§å®éªï¼JDK 7 åç¨
- é¢åæå¡ç«¯ï¼JDK 9 å代 Parallel Scavenge + Parallel Old
- ç»åæ è®°-æ´çãæ è®°-å¤å¶ç®æ³
- é¦åå±é¨å
ååæ¶è®¾è®¡æè·¯
- åºäº Region å
åå¸å±ï¼éç¨ä¸åçç¥å®ç°å代
- ä¸å使ç¨åºå®å¤§å°ãåºå®æ°éçå å
åå代åºååå
- ä¼å
åæ¶ä»·æ¶çæå¤§ç Region
- å个æå¤ä¸ª Humongous åºååæ¾å¤§å¯¹è±¡
- 使ç¨è®°å¿éè§£å³è·¨ Region å¼ç¨é®é¢
- 夿çå¡è¡¨å®ç°ï¼å¯¼è´æ´é«çå
åå ç¨ï¼å ç 10%ï½20%
- å
¨åè½å徿¶éå¨
- è¿½æ±æéçæ¶é´å
æé«æ¶éæçãå»¶è¿å¯æ§çæ
åµä¸æé«ååé
- 追æ±åºä»å
ååé
éçï¼èé䏿¬¡æ§æ¸
æææåå¾å
å
- éç¨äºå¤§å
åå
**Shenandoah**
ç¹ç¹ï¼
- 追æ±ä½å»¶è¿ï¼åé¡¿ 10 毫ç§ä»¥å
- OpenJDK 12 æ°ç¹æ§ï¼RedHat æä¾
- è¿æ¥ç©éµä»£æ¿è®°å¿éï¼éä½å
å使ç¨ä¸ä¼ªå
±äº«é®é¢åºç°æ¦ç
**ZGC**
ç¹ç¹ï¼
- JDK 11 æ°å çå®éªæ§è´¨çæ¶éå¨
- 追æ±ä½å»¶è¿ï¼åé¡¿ 10 毫ç§ä»¥å
- åºäº Region å
åå¸å±
- æªè®¾å代
- 读å±éãæè²æéãå
åå¤éæ å°å®ç°å¯å¹¶åçæ è®°-æ´çç®æ³
- æè²æéåå
åå¤éæ å°è®¾è®¡ç²¾å·§ï¼è§£å³é¨åæ§è½é®é¢ï¼ä½éä½äºå¯ç¨æå¤§å
åãæä½ç³»ç»åéãåªæ¯æ 32 ä½ã䏿¯æå缩æéç
- æç»©äº®ç¼ãæ§è½å½ªæ
### ç产ç¯å¢ç¨çä»ä¹JDKï¼å¦ä½é
ç½®çå徿¶éå¨ï¼
Oracle JDK 1.8
JDK 1.8 䏿 SerialãParNewãParallel ScavengeãSerial OldãParallel OldãCMSãG1ï¼é»è®¤ä½¿ç¨ Parallel Scavenge + Parallel Oldã
- Serial ç³»åæ¯å线ç¨å徿¶éå¨ï¼å¤çæçå¾é«ï¼éåå°å
åã客æ·ç«¯åºæ¯ä½¿ç¨ï¼ä½¿ç¨åæ° -XX:+UseSerialGC æ¾å¼å¯ç¨ã
- Parallel ç³»åç¸å½äºå¹¶åçç Serialï¼è¿½æ±é«ååéï¼éç¨äºè¾å¤§å
å并䏿夿 ¸CPUçç¯å¢ï¼é»è®¤ææ¾å¼ä½¿ç¨åæ° -XX:+UseParallelGC å¯ç¨ãå¯ä»¥ä½¿ç¨ -XX:MaxGCPauseMillis åæ°æå®æå¤§å徿¶éæåæ¯«ç§æ°ï¼æ¶éå¨ä¼å°½éè¾¾å°ç®æ ï¼ä½¿ç¨ -XX:GCTimeRatio æå®ææååé大å°ï¼é»è®¤ 99ï¼ç¨æ·ä»£ç è¿è¡æ¶é´:å徿¶éæ¶é´=99:1ã
- CMSï¼è¿½æ±å徿¶éæåæ¶é´å°½å¯è½çï¼éç¨äºæå¡ç«¯è¾å¤§å
åä¸å¤ CPU çåºç¨ï¼ä½¿ç¨åæ° -XX:+UseConcMarkSweepGC æ¾å¼å¼å¯ï¼ä¼åæ¶ä½ç¨å¹´è½»ä»£ä¸è年代ï¼ä½ææµ®å¨åå¾åå
åç¢çåçé®é¢ã
- G1ï¼ä¸»è¦é¢åæå¡ç«¯åºç¨çå徿¶éå¨ï¼éç¨äºå
·æå¤§å
åç夿 ¸ CPU çæå¡å¨ï¼è¿½æ±è¾å°çå徿¶éæåæ¶é´åè¾é«çååéãé¦åå±é¨å
ååæ¶è®¾è®¡æè·¯ï¼éç¨ä¸åçç¥å®ç°å代ï¼ä¸å使ç¨åºå®å¤§å°ãåºå®æ°éçå å
åå代åºåååï¼èæ¯åºäº Region å
åå¸å±ï¼ä¼å
åæ¶ä»·æ¶çæå¤§ç Regionã使ç¨åæ° -XX:+UseG1GC å¼å¯ã
æä»¬ç产ç¯å¢ä½¿ç¨äº G1 æ¶éå¨ï¼ç¸å
³é
ç½®å¦ä¸
-Xmx12g
-Xms12g
-XX:+UseG1GC
-XX:InitiatingHeapOccupancyPercent=45
-XX:MaxGCPauseMillis=200
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=256m
-XX:MaxDirectMemorySize=512m
-XX:G1HeapRegionSize æªæå®
**æ ¸å¿æè·¯ï¼**
æ¯ä¸ªå
ååºå设置ä¸éï¼é¿å
溢åº
å 设置为æä½ç³»ç»ç 70%å·¦å³ï¼è¶
è¿ 8 Gï¼é¦é G1
æ ¹æ®è年代对象æåé度ï¼è°æ´æ°ç代ä¸è年代ä¹é´çå
忝ä¾
çè¿ GC ä¿¡æ¯ï¼éå¯¹é¡¹ç®ææææ ä¼åï¼æ¯å¦è®¿é®å»¶è¿ãååéç
### è°è°åäº²å§æ´¾æ¨¡å
Parents Delegation Modelï¼è¿éç Parents ç¿»è¯æå亲æç¹ä¸å¦¥ï¼ç±»å è½½åä¸ä¼ éçè¿ç¨ä¸åªæå亲ï¼parents æ´å¤çæ¯å¤çº§åä¸çææã
é¤äºé¡¶å±çå¯å¨ç±»å è½½å¨ï¼å
¶ä»çç±»å è½½å¨å¨å è½½ä¹åï¼é½ä¼å§æ´¾ç»å®çç¶å è½½å¨è¿è¡å è½½ï¼ä¸å±å±åä¸ä¼ éï¼ç´å°ææç¶ç±»å è½½å¨é½æ æ³å è½½ï¼èªå·±æä¼å 载该类ã
åäº²å§æ´¾æ¨¡åï¼æ´å¥½å°è§£å³äºå个类å è½½å¨å使¶åºç¡ç±»çä¸è´æ§é®é¢ï¼é¿å
ç±»çéå¤å è½½ï¼é²æ¢æ ¸å¿APIåºè¢«éæç¯¡æ¹ã
JDK 9 ä¹å
- å¯å¨ç±»å è½½å¨ï¼Bootstrp ClassLoaderï¼ï¼å è½½ /lib/rt.jarã-Xbootclasspath
- æ©å±ç±»å è½½å¨ï¼Extension ClassLoaderï¼sun.misc.Launcher$ExtClassLoaderï¼å è½½ /lib/extãjava.ext.dirs
- åºç¨ç¨åºç±»å è½½å¨ï¼Application ClassLoaderï¼sun.misc.Launcher$AppClassLoaderï¼ï¼å è½½ CLASSPTHã-classpathã-cpãManifest
- èªå®ä¹ç±»å è½½å¨
JDK 9 å¼å§ Extension ClassLoader 被 Platform ClassLoader å代ï¼å¯å¨ç±»å è½½å¨ãå¹³å°ç±»å è½½å¨ãåºç¨ç¨åºç±»å è½½å¨å
¨é½ç»§æ¿äº jdk.internal.loader.BuiltinClassLoader
ç±»å 载代ç é»è¾
```java
protected synchronized Class> loadClass(String name, boolean resolve) throws ClassNotFoundException {
// é¦å
ï¼æ£æ¥è¯·æ±çç±»æ¯å¦å·²ç»è¢«å è½½è¿äº
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// 妿ç¶ç±»å è½½å¨æåºClassNotFoundException
// 说æç¶ç±»å è½½å¨æ æ³å®æå 载请æ±
}
if (c == null) {
// å¨ç¶ç±»å è½½å¨æ æ³å è½½æ¶
// åè°ç¨æ¬èº«çfindClassæ¹æ³æ¥è¿è¡ç±»å è½½
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
```
### ç®åè¯´è¯´ä½ äºè§£çç±»å è½½å¨ï¼å¯ä»¥æç ´åäº²å§æ´¾ä¹ï¼æä¹æç ´ã
**æè·¯ï¼** å
说æä¸ä¸ä»ä¹æ¯ç±»å è½½å¨ï¼å¯ä»¥ç»é¢è¯å®ç»ä¸ªå¾ï¼å说ä¸ä¸ç±»å è½½å¨åå¨çæä¹ï¼è¯´ä¸ä¸åäº²å§æ´¾æ¨¡åï¼æåéè¿°æä¹æç ´åäº²å§æ´¾æ¨¡åã
**æççæ¡ï¼**
**1) ä»ä¹æ¯ç±»å è½½å¨ï¼**
**ç±»å è½½å¨** å°±æ¯æ ¹æ®æå®å
¨éå®åç§°å°classæä»¶å è½½å°JVMå
åï¼è½¬ä¸ºClass对象ã
> * å¯å¨ç±»å è½½å¨ï¼Bootstrap ClassLoaderï¼ï¼ç±C++è¯è¨å®ç°ï¼é对HotSpotï¼,è´è´£å°åæ¾å¨\libç®å½æ-Xbootclasspathåæ°æå®çè·¯å¾ä¸çç±»åºå è½½å°å
åä¸ã
> * å
¶ä»ç±»å è½½å¨ï¼ç±Javaè¯è¨å®ç°ï¼ç»§æ¿èªæ½è±¡ç±»ClassLoaderãå¦ï¼
>
> > * æ©å±ç±»å è½½å¨ï¼Extension ClassLoaderï¼ï¼è´è´£å è½½\lib\extç®å½æjava.ext.dirsç³»ç»åéæå®çè·¯å¾ä¸çææç±»åºã
> > * åºç¨ç¨åºç±»å è½½å¨ï¼Application ClassLoaderï¼ãè´è´£å è½½ç¨æ·ç±»è·¯å¾ï¼classpathï¼ä¸çæå®ç±»åºï¼æä»¬å¯ä»¥ç´æ¥ä½¿ç¨è¿ä¸ªç±»å è½½å¨ãä¸è¬æ
åµï¼å¦ææä»¬æ²¡æèªå®ä¹ç±»å è½½å¨é»è®¤å°±æ¯ç¨è¿ä¸ªå è½½å¨ã
**2ï¼åäº²å§æ´¾æ¨¡å**
**åäº²å§æ´¾æ¨¡åå·¥ä½è¿ç¨æ¯ï¼**
> 妿ä¸ä¸ªç±»å è½½å¨æ¶å°ç±»å è½½ç请æ±ï¼å®é¦å
ä¸ä¼èªå·±å»å°è¯å è½½è¿ä¸ªç±»ï¼èæ¯æè¿ä¸ªè¯·æ±å§æ´¾ç»ç¶ç±»å è½½å¨å®æãæ¯ä¸ªç±»å è½½å¨é½æ¯å¦æ¤ï¼åªæå½ç¶å è½½å¨å¨èªå·±çæç´¢èå´å
æ¾ä¸å°æå®çç±»æ¶ï¼å³ClassNotFoundExceptionï¼ï¼åå è½½å¨æä¼å°è¯èªå·±å»å è½½ã
åäº²å§æ´¾æ¨¡åå¾ï¼

**3ï¼ä¸ºä»ä¹éè¦åäº²å§æ´¾æ¨¡åï¼**
å¨è¿éï¼å
æ³ä¸ä¸ï¼å¦ææ²¡æåäº²å§æ´¾ï¼é£ä¹ç¨æ·æ¯ä¸æ¯å¯ä»¥**èªå·±å®ä¹ä¸ä¸ªjava.lang.Objectçååç±»**ï¼**java.lang.Stringçååç±»**ï¼å¹¶æå®æ¾å°ClassPathä¸,é£ä¹**ç±»ä¹é´çæ¯è¾ç»æåç±»çå¯ä¸æ§å°æ æ³ä¿è¯**ï¼å æ¤ï¼ä¸ºä»ä¹éè¦åäº²å§æ´¾æ¨¡åï¼**鲿¢å
åä¸åºç°å¤ä»½åæ ·çåèç **
**4ï¼æä¹æç ´åäº²å§æ´¾æ¨¡åï¼**
æç ´åäº²å§æ´¾æºå¶åä¸ä»
**è¦ç»§æ¿ClassLoader**ç±»ï¼è¿è¦**éåloadClassåfindClass**æ¹æ³ã
### å举ä¸äºä½ ç¥éçæç ´åäº²å§æ´¾æºå¶çä¾åã为ä»ä¹è¦æç ´ï¼
- JNDI éè¿å¼å
¥çº¿ç¨ä¸ä¸æç±»å è½½å¨ï¼å¯ä»¥å¨ Thread.setContextClassLoader æ¹æ³è®¾ç½®ï¼é»è®¤æ¯åºç¨ç¨åºç±»å è½½å¨ï¼æ¥å è½½ SPI ç代ç ãæäºçº¿ç¨ä¸ä¸æç±»å è½½å¨ï¼å°±å¯ä»¥å®æç¶ç±»å è½½å¨è¯·æ±åç±»å è½½å¨å®æç±»å è½½çè¡ä¸ºãæç ´çåå ï¼æ¯ä¸ºäº JNDI æå¡çç±»å è½½å¨æ¯å¯å¨å¨ç±»å è½½ï¼ä¸ºäºå®æé«çº§ç±»å è½½å¨è¯·æ±åç±»å è½½å¨ï¼å³ä¸æä¸ç线ç¨ä¸ä¸æå è½½å¨ï¼å 载类ã
- Tomcatï¼åºç¨çç±»å è½½å¨ä¼å
èªè¡å è½½åºç¨ç®å½ä¸ç classï¼å¹¶ä¸æ¯å
å§æ´¾ç»ç¶å è½½å¨ï¼å è½½ä¸äºæå§æ´¾ç»ç¶å è½½å¨ãæç ´çç®çæ¯ä¸ºäºå®æåºç¨é´çç±»é离ã
- OSGiï¼å®ç°æ¨¡ååçé¨ç½²ï¼ä¸ºæ¯ä¸ªæ¨¡åé½èªå®ä¹äºç±»å è½½å¨ï¼éè¦æ´æ¢æ¨¡åæ¶ï¼æ¨¡åä¸ç±»å è½½å¨ä¸èµ·æ´æ¢ãå
¶ç±»å è½½çè¿ç¨ä¸ï¼æå¹³çº§çç±»å è½½å¨å è½½è¡ä¸ºãæç ´çåå æ¯ä¸ºäºå®ç°æ¨¡åçæ¿æ¢ã
- JDK 9ï¼Extension ClassLoader 被 Platform ClassLoader å代ï¼å½å¹³å°ååºç¨ç¨åºç±»å è½½å¨æ¶å°ç±»å 载请æ±ï¼å¨å§æ´¾ç»ç¶å è½½å¨å è½½åï¼è¦å
å¤æè¯¥ç±»æ¯å¦è½å¤å½å±å°æä¸ä¸ªç³»ç»æ¨¡åä¸ï¼å¦æå¯ä»¥æ¾å°è¿æ ·çå½å±å
³ç³»ï¼å°±è¦ä¼å
å§æ´¾ç»è´è´£é£ä¸ªæ¨¡åçå è½½å¨å®æå è½½ãæç ´çåå ï¼æ¯ä¸ºäºæ·»å 模ååçç¹æ§ã
### æä¹æåºçº¿ç¨æ ä¿¡æ¯ã
**æè·¯ï¼** å¯ä»¥è¯´ä¸ä¸jpsï¼top ï¼jstackè¿å 个å½ä»¤ï¼åé
å䏿¬¡ææ¥çº¿ä¸é®é¢è¿è¡è§£çã
**æççæ¡ï¼**
* è¾å
¥jpsï¼è·å¾è¿ç¨å·ã
* top -Hp pid è·åæ¬è¿ç¨ä¸ææçº¿ç¨çCPUèæ¶æ§è½
* jstack pidå½ä»¤æ¥çå½åjavaè¿ç¨çå æ ç¶æ
* æè
jstack -l > /tmp/output.txt æå æ ä¿¡æ¯æå°ä¸ä¸ªtxtæä»¶ã
* å¯ä»¥ä½¿ç¨fastthread å æ å®ä½ï¼[fastthread.io/](http://fastthread.io/)
### 强å¼ç¨ã软å¼ç¨ãå¼±å¼ç¨ãèå¼ç¨çåºå«ï¼
**æè·¯ï¼** å
说ä¸ä¸åç§å¼ç¨çå®ä¹ï¼å¯ä»¥ç»å代ç 讲ä¸ä¸ï¼ä¹å¯ä»¥æ©å±è°å°ThreadLocalMapéå¼±å¼ç¨ç¨å¤ã
**æççæ¡ï¼**
**1ï¼å¼ºå¼ç¨**
æä»¬å¹³æ¶newäºä¸ä¸ªå¯¹è±¡å°±æ¯å¼ºå¼ç¨ï¼ä¾å¦ Object obj = new Object();å³ä½¿å¨å
åä¸è¶³çæ
åµä¸ï¼JVM宿¿æåºOutOfMemoryé误ä¹ä¸ä¼åæ¶è¿ç§å¯¹è±¡ã
**2ï¼è½¯å¼ç¨**
妿ä¸ä¸ªå¯¹è±¡åªå
·æè½¯å¼ç¨ï¼åå
å空é´è¶³å¤ï¼åå¾åæ¶å¨å°±ä¸ä¼åæ¶å®ï¼å¦æå
å空é´ä¸è¶³äºï¼å°±ä¼åæ¶è¿äºå¯¹è±¡çå
åã
```
SoftReference softRef=new SoftReference(str); // 软å¼ç¨
```
**ç¨å¤ï¼** 软å¼ç¨å¨å®é
䏿éè¦çåºç¨ï¼ä¾å¦æµè§å¨çåéæé®ãæåéæ¶ï¼è¿ä¸ªåéæ¶æ¾ç¤ºçç½é¡µå
容æ¯éæ°è¿è¡è¯·æ±è¿æ¯ä»ç¼åä¸ååºå¢ï¼è¿å°±è¦çå
·ä½çå®ç°çç¥äºã
ï¼1ï¼å¦æä¸ä¸ªç½é¡µå¨æµè§ç»ææ¶å°±è¿è¡å
容çåæ¶ï¼åæå鿥çå颿µè§è¿ç页颿¶ï¼éè¦éæ°æå»º
ï¼2ï¼å¦æå°æµè§è¿çç½é¡µåå¨å°å
åä¸ä¼é æå
åç大鿵ªè´¹ï¼çè³ä¼é æå
åæº¢åº
å¦ä¸ä»£ç ï¼
```
Browser prev = new Browser(); // è·å页é¢è¿è¡æµè§
SoftReference sr = new SoftReference(prev); // æµè§å®æ¯å置为软å¼ç¨
if(sr.get()!=null){
rev = (Browser) sr.get(); // è¿æ²¡æè¢«åæ¶å¨åæ¶ï¼ç´æ¥è·å
}else{
prev = new Browser(); // ç±äºå
ååç´§ï¼æä»¥å¯¹è½¯å¼ç¨çå¯¹è±¡åæ¶äº
sr = new SoftReference(prev); // éæ°æå»º
}
```
**3ï¼å¼±å¼ç¨**
å
·æå¼±å¼ç¨çå¯¹è±¡æ¥ææ´çæççå½å¨æãå¨åå¾åæ¶å¨çº¿ç¨æ«æå®æç®¡è¾çå
ååºåçè¿ç¨ä¸ï¼ä¸æ¦åç°äºåªå
·æå¼±å¼ç¨ç对象ï¼ä¸ç®¡å½åå
å空é´è¶³å¤ä¸å¦ï¼é½ä¼åæ¶å®çå
åã
```
String str=new String("abc");
WeakReference abcWeakRef = new WeakReference(str);
str=null;
çä»·äº
str = null;
System.gc();
```
**4ï¼èå¼ç¨**
妿ä¸ä¸ªå¯¹è±¡ä»
ææèå¼ç¨ï¼é£ä¹å®å°±å没æä»»ä½å¼ç¨ä¸æ ·ï¼å¨ä»»ä½æ¶åé½å¯è½è¢«åå¾åæ¶å¨åæ¶ãèå¼ç¨ä¸»è¦ç¨æ¥è·è¸ªå¯¹è±¡è¢«åå¾åæ¶å¨åæ¶çæ´»å¨ã
### safepoint æ¯ä»ä¹ï¼
为äºåå°å¯¹è±¡å¼ç¨çæ«æï¼ä½¿ç¨ OopMap çæ°æ®ç»æå¨ç¹å®çä½ç½®è®°å½ä¸æ éåå¯åå¨éåªäºä½ç½®æ¯å¼ç¨ï¼
ä½ä¸ºäºé¿å
ç»æ¯æ¡æä»¤é½çæ OopMap è®°å½å ç¨å¤§éå
åçé®é¢ï¼åªå¨ç¹å®ä½ç½®è®°å½è¿äºä¿¡æ¯ã
å®å
¨ç¹çé宿¢ä¸è½å¤ªå°ä»¥è³äºè®©æ¶éå¨çå¾
æ¶é´è¿é¿ï¼ä¹ä¸è½å¤ªè¿é¢ç¹ä»¥è³äºè¿åå¢å¤§è¿è¡æ¶çå
åè´è·ãå®å
¨ç¹ä½ç½®çéååºæ¬ä¸æ¯ä»¥âæ¯å¦å
·æè®©ç¨åºé¿æ¶é´æ§è¡çç¹å¾â为æ åè¿è¡éå®çï¼å¦æ¹æ³è°ç¨ã循ç¯è·³è½¬ãå¼å¸¸è·³è½¬çé½å±äºæä»¤åºåå¤ç¨ã
### MinorGCãMajorGCãFullGC ä»ä¹æ¶ååçï¼
- MinorGC å¨å¹´è½»ä»£ç©ºé´ä¸è¶³çæ¶ååç
- MajorGC æçæ¯è年代ç GCï¼åºç° MajorGC ä¸è¬ç»å¸¸ä¼´æ MinorGC
- FullGC èå¹´ä»£æ æ³ååé
å
åï¼å
空é´ä¸è¶³ï¼æ¾ç¤ºè°ç¨ System.gcï¼å CMS ä¸ç±»çåå¾åæ¶å¨ï¼å¨ MinorGC åºç° promotion failure æ¶ä¹ä¼åç FullGC
### 说说类å è½½çè¿ç¨
- å è½½ï¼Loadingï¼ï¼éè¿ä¸ä¸ªç±»çå
¨éå®åæ¥è·åå®ä¹æ¤ç±»çäºè¿å¶åèæµï¼å°è¿ä¸ªåèæµæä»£è¡¨çéæåå¨ç»æè½¬åä¸ºæ¹æ³åºçè¿è¡æ¶æ°æ®ç»æï¼å¨å
åä¸çæä¸ä¸ªä»£è¡¨è¿ä¸ªç±»çjava.lang.Class对象ï¼ä½ä¸ºæ¹æ³åºè¿ä¸ªç±»çåç§æ°æ®ç访é®å
¥å£ã
- éªè¯ï¼Verificationï¼ï¼ç¡®ä¿Classæä»¶çåèæµä¸å
å«çä¿¡æ¯ç¬¦åãJavaèææºè§èãçå
¨é¨çº¦æè¦æ±ï¼ä¿è¯è¿äºä¿¡æ¯è¢«å½ä½ä»£ç è¿è¡åä¸ä¼å±å®³èææºèªèº«çå®å
¨ã
- åå¤ï¼Preparationï¼ï¼æ£å¼ä¸ºç±»ä¸å®ä¹çåéï¼å³éæåéï¼è¢«static修饰çåéï¼åé
å
å并设置类åéåå§å¼ã
- è§£æï¼Resolutionï¼ï¼æ¯ JVM å°å¸¸éæ± å
ç符å·å¼ç¨æ¿æ¢ä¸ºç´æ¥å¼ç¨çè¿ç¨ã
- åå§åï¼Initializationï¼ï¼æ§è¡ç±»æé å¨ æ¹æ³çè¿ç¨ï¼æ§è¡ææç±»åéçèµå¼å¨ä½åéæè¯å¥åï¼static{}åï¼ã
å
¶ä¸éªè¯ãåå¤ãè§£æç»ç§°ä¸ºç§°ä¸ºè¿æ¥ï¼Linkingï¼
### å¯ä»¥æè¿°ä¸ä¸ class æä»¶çç»æåï¼
Class æä»¶å
å«äº Java èææºçæä»¤éã符å·è¡¨ãè¾
å©ä¿¡æ¯çåèç (Byte Code)ï¼æ¯å®ç°è·¨æä½ç³»ç»åè¯è¨æ å
³æ§çåºç³ä¹ä¸ã
ä¸ä¸ª Class æä»¶å®ä¹äºä¸ä¸ªç±»ææ¥å£çä¿¡æ¯ï¼æ¯ä»¥ 8 个åè为åä½ï¼æ²¡æåéç¬¦ï¼æé¡ºåºç´§åæå¨ä¸èµ·çäºè¿å¶æµã
ç¨ "æ ç¬¦å·æ°" å "表" ç»æçä¼ªç»ææ¥å卿°æ®ã
- æ ç¬¦å·æ°ï¼åºæ¬æ°æ®ç±»åï¼ç¨æ¥æè¿°æ°åãç´¢å¼å¼ç¨ãæ°éå¼ãå符串å¼ï¼å¦u1ãu2 åå«è¡¨ç¤º 1 个åèã2 个åè
- è¡¨ï¼æ ç¬¦å·æ°åå
¶ä»è¡¨ç»æï¼å½åä¸è¬ä»¥ "_info" ç»å°¾
ç»æé¨å
**1ãéæ° Magic Number**
- Class æä»¶å¤´ 4 个åèï¼0xCAFEBABE
- ä½ç¨æ¯ç¡®å®è¯¥æä»¶æ¯ Class æä»¶
**2ãçæ¬å·**
- 4 个åèï¼å 2 ä¸ªæ¯æ¬¡çæ¬å· Minor Versionï¼å 2 ä¸ªä¸»çæ¬å· Major Version
- ä» 45 (JDK1.0) å¼å§ï¼å¦ 0x00000032 转åè¿å¶å°±æ¯ 50ï¼ä»£è¡¨ JDK 6
- ä½çæ¬çèææºè·ä¸äºé«çæ¬ç Class æä»¶
**3ã叏鿱 **
- 常é容é计æ°å¼(constant_pool_count)ï¼u2ï¼ä» 1 å¼å§ãå¦ 0x0016 åè¿å¶ 22 代表æ 21 项常é
- æ¯é¡¹å¸¸é齿¯ä¸ä¸ªè¡¨ï¼ç®å 17 ç§
- ç¹ç¹ï¼Class æä»¶ä¸æå¤§æ°æ®é¡¹ç®ä¹ä¸ã第ä¸ä¸ªåºç°è¡¨æ°æ®ç»æ
**4ãè®¿é®æ å¿**
- 2 个åèï¼è¡¨ç¤ºç±»ææ¥å£çè®¿é®æ å¿
**5ã类索å¼ãç¶ç±»ç´¢å¼ãæ¥å£ç´¢å¼éå**
- 类索å¼(this_class)ãç¶ç±»ç´¢å¼(super_class)ï¼u2
- æ¥å£ç´¢å¼éå(interfaces)ï¼u2 éå
- 类索å¼ç¡®å®ç±»çå
¨éå®åãç¶ç±»ç´¢å¼ç¡®å®ç¶ç±»çå
¨éå®åãæ¥å£ç´¢å¼éåç¡®å®å®ç°æ¥å£
- ç´¢å¼å¼å¨å¸¸éæ± ä¸æ¥æ¾å¯¹åºç常é
**6ãåæ®µè¡¨(field_info)éå**
- æè¿°æ¥å£æç±»ç³æçåé
- fields_countï¼u2ï¼è¡¨ç¤ºå段表æ°éï¼å颿¥çç¸åºæ°éçåæ®µè¡¨
- 9 ç§åæ®µè®¿é®æ å¿
**7ãæ¹æ³è¡¨(method_info)éå**
- æè¿°æ¥å£æç±»ç³æçæ¹æ³
- methods_countï¼u2ï¼è¡¨ç¤ºæ¹æ³è¡¨æ°éï¼å颿¥çç¸åºæ°éçæ¹æ³è¡¨
- 12 ç§æ¹æ³è®¿é®æ å¿
- æ¹æ³è¡¨ç»æä¸åæ®µè¡¨ç»æä¸è´
**8ã屿§è¡¨(attribute_info)éå**
- class æä»¶ãåæ®µè¡¨ãæ¹æ³è¡¨å¯æºå¸¦å±æ§éåï¼æè¿°ç¹æä¿¡æ¯
- é¢å®ä¹ 29 项屿§ï¼å¯èªå®ä¹åå
¥ä¸éå屿§

### 说说 JVM å¦ä½æ§è¡ class ä¸çåèç ã
JVM å
å è½½å
å«åèç ç class æä»¶ï¼åæ¾å¨æ¹æ³åºï¼å®é
è¿è¡æ¶ï¼èææºä¼æ§è¡æ¹æ³åºå
ç代ç ãJava èææºå¨å
åä¸åååºæ åå æ¥åå¨è¿è¡æ¶çæ°æ®ã
è¿è¡è¿ç¨ä¸ï¼æ¯å½è°ç¨è¿å
¥ Java æ¹æ³ï¼é½ä¼å¨ Java æ¹æ³æ ä¸çæä¸ä¸ªæ 帧ï¼ç¨æ¥æ¯æèææºè¿è¡æ¹æ³çè°ç¨ä¸æ§è¡ï¼å
å«äºå±é¨åé表ãæä½æ°æ ã卿龿¥ãæ¹æ³è¿åå°åçä¿¡æ¯ã
å½éåºå½åæ§è¡çæ¹æ³æ¶ï¼ä¸ç®¡æ£å¸¸è¿åè¿æ¯å¼å¸¸è¿åï¼Java èææºåä¼å¼¹åºå½å线ç¨çå½åæ 帧ï¼å¹¶å°ä¹èå¼ã
æ¹æ³çè°ç¨ï¼éè¦éè¿è§£æå®æç¬¦å·å¼ç¨å°ç´æ¥å¼ç¨ï¼éè¿åæ´¾å®æå¨ææ¾å°è¢«è°ç¨çæ¹æ³ã
ä»ç¡¬ä»¶è§åº¦æ¥çï¼Java åèç æ æ³ç´æ¥æ§è¡ãå æ¤ï¼Java èææºéè¦å°åèç ç¿»è¯ææºå¨ç ãç¿»è¯è¿ç¨ç±ä¸¤ç§å½¢å¼ï¼ç¬¬ä¸ç§æ¯è§£éæ§è¡ï¼å³å°éå°çåèä¸è¾¹ç ç¿»è¯ææºå¨ç ä¸è¾¹æ§è¡ï¼ç¬¬äºç§æ¯å³æ¶ç¼è¯(Just-In-Time compilation,JIT)ï¼å³å°ä¸ä¸ªæ¹æ³ä¸å
å«çææåèç ç¼è¯ææºå¨ç ååæ§è¡ãå¨ HotSpot é两è
齿ï¼è§£éæ§è¡å¨å¯å¨æ¶è约ç¼è¯æ¶é´æ§è¡é度è¾å¿«ï¼éçæ¶é´çæ¨ç§»ï¼ç¼è¯å¨éæ¸ä¼è¿åä½ç¨ï¼æè¶æ¥è¶å¤ç代ç ç¼è¯ææ¬å°ä»£ç åï¼å¯ä»¥è·åæ´é«çæ§è¡æçã
### ç产ç¯å¢ CPU å ç¨è¿é«ï¼ä½ å¦ä½è§£å³ï¼
**1ã** top + H æä»¤æ¾åºå ç¨ CPU æé«çè¿ç¨ç pid
**2ã** top -H -p
å¨è¯¥è¿ç¨ä¸æ¾å°ï¼åªäºçº¿ç¨å ç¨ç CPU æé«ç线ç¨ï¼è®°å½ä¸ tid
**3ã** jstack -l
\> threads.txtï¼å¯¼åºè¿ç¨ççº¿ç¨æ ä¿¡æ¯å°ææ¬ï¼å¯¼åºåºç°å¼å¸¸çè¯ï¼å ä¸ -F åæ°
**4ã** å° tid 转æ¢ä¸ºåå
è¿å¶ï¼å¨ threads.txt ä¸æç´¢ï¼æ¥å°å¯¹åºç线ç¨ä»£ç æ§è¡æ ï¼å¨ä»£ç 䏿¥æ¾å CPU æ¯è¾é«çåå ãå
¶ä¸ tid 转åå
è¿å¶ï¼å¯ä»¥åå© Linux ç printf "%x" tid æä»¤
æç¨ä¸è¿°æ¹æ³æ¥å°è¿ï¼jvm 夿¡çº¿ç¨ç¯ç full gc 导è´çCPU 100% çé®é¢å JDK1.6 HashMap å¹¶å put 导è´çº¿ç¨ CPU 100% çé®é¢
### ç产ç¯å¢æå¡å¨åæ
¢ï¼å¦ä½è¯æå¤çï¼
ä½¿ç¨ top æä»¤ï¼æå¡å¨ä¸ CPU å å
åçä½¿ç¨æ
åµï¼-H å¯ä»¥æ CPU 使ç¨çéåºï¼-M å
å使ç¨çéåºãæé¤å
¶ä»è¿ç¨å ç¨è¿é«çç¡¬ä»¶èµæºï¼å¯¹ Java æå¡é æå½±åã
妿åç° CPU 使ç¨è¿é«ï¼å¯ä»¥ä½¿ç¨ top æä»¤æ¥åº JVM ä¸å ç¨ CPU è¿é«ç线ç¨ï¼éè¿ jstack æ¾å°å¯¹åºç线ç¨ä»£ç è°ç¨ï¼ææ¥åºé®é¢ä»£ç ã
妿åç°å
å使ç¨çæ¯è¾é«ï¼å¯ä»¥ dump åº JVM å å
åï¼ç¶ååå© MAT è¿è¡åæï¼æ¥åºå¤§å¯¹è±¡æè
å ç¨æå¤ç对象æ¥èªåªéï¼ä¸ºä»ä¹ä¼é¿æ¶é´å ç¨è¿ä¹å¤ï¼å¦æ dump åºçå å
åæä»¶æ£å¸¸ï¼æ¤æ¶å¯ä»¥èèå å¤å
å被大é使ç¨å¯¼è´åºç°é®é¢ï¼éè¦å婿ä½ç³»ç»æä»¤ pmap æ¥åºè¿ç¨çå
ååé
æ
åµãgdb dump åºå
·ä½å
åä¿¡æ¯ãperf æ¥çæ¬å°å½æ°è°ç¨çã
妿 CPU å å
å使ç¨çé½å¾æ£å¸¸ï¼é£å°±éè¦è¿ä¸æ¥å¼å¯ GC æ¥å¿ï¼åæç¨æ·çº¿ç¨æåçæ¶é´ãåé¨åå
ååºå GC 次æ°åæ¶é´çææ ï¼å¯ä»¥åå© jstat æå¯è§åå·¥å
· GCeasy çï¼å¦æé®é¢åºå¨ GC ä¸é¢çè¯ï¼èèæ¯å¦æ¯å
åä¸å¤ãæ ¹æ®åå¾å¯¹è±¡çç¹ç¹è¿è¡åæ°è°ä¼ãä½¿ç¨æ´éåçå徿¶éå¨ï¼åæ jstack åºæ¥çå个线ç¨ç¶æã妿é®é¢å®å¨æ¯è¾éè½ï¼èèæ¯å¦å¯ä»¥å¼å¯ jmxï¼ä½¿ç¨ visualmv çå¯è§åå·¥å
·è¿ç¨çæ§ä¸åæã