# Java Notes
## Recent
è½»éçº§éæ¯ JVM èªå·±ç®¡ç线ç¨ï¼ééçº§éæ¯äº¤ç»æä½ç³»ç»ç®¡ç线ç¨
[Backend Developer Roadmap: Learn to become a modern backend developer](https://roadmap.sh/backend)
non-volatile memory (NVM)ï¼éæå¤±æ§åå¨å¨ï¼NVMï¼æ¯ä¸ç§è®¡ç®æºåå¨å¨ï¼å³ä½¿çµæºå
³éä¹å
·æä¿åå·²ä¿åæ°æ®çè½åã 䏿失æ§åå¨å¨ä¸åï¼NVMä¸éè¦å®æå·æ°å
¶åå¨å¨æ°æ®
non-uniform memory access (NUMA)ï¼éç»ä¸å
å访é®ï¼NUMAï¼æ¯ä¸ç§ç¨äºå¤å¤çå¨ççµèå
åä½è®¾è®¡ï¼å
åè®¿é®æ¶é´åå³äºå¤çå¨çå
åä½ç½®
Jakarta (/dÊÉËkÉËrtÉ/
[What's new in Java 11 (Changes in JDK 9, 10, 11)](https://www.hackingnote.com/en/java/java-11)
[What's new in Java 17](https://www.hackingnote.com/en/java/java-17)
`java.util.concurrent.CopyOnWriteArrayList`
`AtomicInteger`åºå±å®ç°æºå¶
`strace -o call.syscalls.log java example` è¾åºç³»ç»è°ç¨æ¥å¿
### Concurrent vs. Parallel
å¹¶å Concurrent å¹¶åæè½å¤è®©å¤ä¸ªä»»å¡å¨é»è¾ä¸äº¤ç»æ§è¡çç¨åºè®¾è®¡
```shell
-- -- --
/ \
>---- -- -- -- -- ---->>
```
å¹¶è¡ Parallel å¹¶è¡æç©çä¸åæ¶æ§è¡
```shell
------
/ \
>-------------->>
```
### 常ç¨åæ°
* `java -XX:+PrintFlagsFinal -version` æ¥çJVMåæ°çé»è®¤å¼
* `-Xss256k, -XX:ThreadStackSize=1024` default Linux/x86 (64-bit): 1 MB `java -XX:+PrintFlagsFinal -version | grep ThreadStackSize`
* `-XX:MaxMetaspaceSize=128m` é»è®¤å¼å¾å¤§ï¼`CompressedClassSpaceSize` é»è®¤ä¹æ1G
[Configuring Stack Sizes in the JVM | Baeldung](https://www.baeldung.com/jvm-configure-stack-sizes)
## Java website
JDK 䏿°ç¹æ§ï¼Java ä¸åçæ¬çæ¯è¾å¯ä»¥åèï¼ççå¢å äºåªäºé¡¹ï¼åºå¼äºåªäºé¡¹ï¼æè
æ¯ç§»é¤äºåªäºé¡¹
* [Java Version Almanac Javaçæ¬å¹´é´](https://javaalmanac.io/): Collection of information about the history and future of Java.
* [Foojay Almanac](https://foojay.io/almanac/jdk-17/): a central resource for the Java communityâs daily âinformation
* [OpenJDK Javaå¢å¼ºææ¡ï¼JEPï¼](https://openjdk.java.net/jeps/0) å½¢å¼è¿è¡çåæ´
* Oracle [åå¸è¯´æ](https://www.oracle.com/java/technologies/javase/16-relnote-issues.html) å¯ä»¥æ¥é
æ¯ä¸ª Java çæ¬ç详ç»ä¿¡æ¯
## Java 21
[What's new in Java 21](https://www.hackingnote.com/en/java/java-21/index.html)
## Java 17
[JDK 17 Documentation](https://docs.oracle.com/en/java/javase/17/)
[JDK 17 readme](https://www.oracle.com/java/technologies/javase/jdk17-readme-downloads.html)
[JDK 17 Tool Specifications](https://docs.oracle.com/en/java/javase/17/docs/specs/man/index.html)
[JDK 17 New Feature](https://www.oracle.com/java/technologies/javase/17-relnote-issues.html#NewFeature)
[What's new in Java 17](https://www.hackingnote.com/en/java/java-17/index.html)
[Java Version Almanac - Java 17 - foojay](https://foojay.io/almanac/java-17/)
[JDK 17 Books](https://docs.oracle.com/en/java/javase/17/books.html)
JEP-374: Disable and Deprecate Biased Locking
### Flight Recorder
[Flight Recorder API Programmerâs Guide](https://docs.oracle.com/en/java/javase/17/jfapi/creating-and-recording-your-first-event.html)
[The jfr Command](https://docs.oracle.com/en/java/javase/17/docs/specs/man/jfr.html)
## Java 8
[New APIs in Java 8 - javaalmanac.io](https://javaalmanac.io/jdk/8/apidiff/6/)
method reference :: syntax (meaning âuse this method as a valueâ
`File[] hiddenFiles = new File(".").listFiles(File::isHidden);`
LocalDate, LocalTime, LocalDateTime æ¯æ¹ä¾¿ç¨æ·ä½¿ç¨ï¼Instant 精确å°çº³ç§ï¼æ¹ä¾¿çµèè¯å«
Duration 精确å°ç§æè
纳ç§: You can create a duration between two LocalTimes, two LocalDateTimes, or two Instants
Period 精确å°å¤© You can find out the difference between two LocalDates
DateTimeFormatter
## Java lock
### éé级
* [JEP draft: Concurrent Monitor Deflation](http://openjdk.java.net/jeps/8183909)
* [ä¸å¯ä¸è¯´çJavaâéâäº](https://tech.meituan.com/2018/11/15/java-lock.html)
* [JEP 374: Deprecate and Disable Biased Locking, Release jdk 15](https://openjdk.java.net/jeps/374)
* [Javaåå鿝å¦ä½æ¤éçï¼](https://www.zhihu.com/question/57774162)
* [Java Language Specification Chapter 17. Threads and Locks](https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html)
* [Synchronization and Object Locking](https://wiki.openjdk.java.net/display/HotSpot/Synchronization)
## JVM å
ååé
å¨Javaèææºä¸ï¼å
åå为ä¸ä¸ªä»£ï¼æ°ç代ï¼Newï¼ãèç代ï¼Oldï¼ãæ°¸ä¹
代ï¼Permï¼ã
ï¼1ï¼æ°ç代Newï¼æ°å»ºç对象é½åæ¾è¿é
ï¼2ï¼èç代Oldï¼åæ¾ä»æ°ç代Newä¸è¿ç§»è¿æ¥ççå½å¨æè¾ä¹
çå¯¹è±¡ãæ°ç代Newåèç代Oldå
±åç»æäºå å
åã
ï¼3ï¼æ°¸ä¹
代Permï¼æ¯éå å
åçç»æé¨åã主è¦åæ¾å è½½çClass类级对象å¦classæ¬èº«ï¼methodï¼fieldççã
* å å
å = 年轻代 + å¹´è代 + æ°¸ä¹
代
* 年轻代 = Edenåº + 两个Survivoråºï¼FromåToï¼
妿åºç°java.lang.OutOfMemoryError: Java heap spaceå¼å¸¸ï¼è¯´æJavaèææºçå å
åä¸å¤ãåå æäºï¼
ï¼1ï¼Javaèææºçå å
å设置ä¸å¤ï¼å¯ä»¥éè¿åæ°-Xms1gã-Xmx2gæ¥è°æ´ã
ï¼2ï¼ä»£ç ä¸å建äºå¤§é大对象ï¼å¹¶ä¸é¿æ¶é´ä¸è½è¢«å徿¶é卿¶éï¼åå¨è¢«å¼ç¨ï¼ã
妿åºç°java.lang.OutOfMemoryError: PermGen spaceï¼è¯´ææ¯Javaèææºå¯¹æ°¸ä¹
代Permå
å设置ä¸å¤ã
ä¸è¬åºç°è¿ç§æ
åµï¼é½æ¯ç¨åºå¯å¨éè¦å 载大éçç¬¬ä¸æ¹jarå
ãä¾å¦ï¼å¨ä¸ä¸ªTomcatä¸é¨ç½²äºå¤ªå¤çåºç¨ã
ä»ä»£ç çè§åº¦ï¼è½¯ä»¶å¼å人å主è¦å
³æ³¨java.lang.OutOfMemoryError: Java heap spaceå¼å¸¸ï¼åå°ä¸å¿
è¦ç对象å建ï¼åæ¶é¿å
å
åæ³æ¼ã
### Metaspace
`MetaspaceSize` é»è®¤20.8Må·¦å³(x86ä¸å¼å¯c2模å¼)ï¼ä¸»è¦æ¯æ§å¶metaspaceGCåççåå§éå¼ï¼ä¹æ¯æå°éå¼ï¼ä½æ¯è§¦åmetaspaceGCçé弿¯ä¸æååçï¼ä¸ä¹å¯¹æ¯çä¸»è¦æ¯æKlass Metaspaceä¸NoKlass Metaspace两åcommittedçå
ååã
`MaxMetaspaceSize` é»è®¤åºæ¬æ¯æ 穷大ï¼ä½æ¯æè¿æ¯å»ºè®®å¤§å®¶è®¾ç½®è¿ä¸ªåæ°ï¼å 为å¾å¯è½ä¼å 为没æéå¶è导è´metaspaceè¢«æ æ¢å¢ä½¿ç¨(ä¸è¬æ¯å
åæ³æ¼)è被OS Killãè¿ä¸ªåæ°ä¼éå¶metaspace(å
æ¬äºKlass Metaspace以åNoKlass Metaspace)被committedçå
å大å°ï¼ä¼ä¿è¯committedçå
åä¸ä¼è¶
è¿è¿ä¸ªå¼ï¼ä¸æ¦è¶
è¿å°±ä¼è§¦åGCï¼è¿éè¦æ³¨æåMaxPermSizeçåºå«ï¼MaxMetaspaceSizeå¹¶ä¸ä¼å¨jvmå¯å¨çæ¶ååé
ä¸åè¿ä¹å¤§çå
ååºæ¥ï¼èMaxPermSizeæ¯ä¼åé
ä¸åè¿ä¹å¤§çå
åçã
[JVMæºç åæä¹Metaspaceè§£å¯-é¿éäºå¼åè
社åº](https://developer.aliyun.com/article/73601)
### åæå¯¹è±¡çå
åå ç¨
[synchronized æ«å¶äºç¬è®°](https://cloud.fynote.com/share/d/3225#éå级è¿ç¨_53)
å¨HotSpotèææºéï¼å¯¹è±¡å¨å å
åä¸çåå¨å¸å±å¯ä»¥åå为ä¸ä¸ªé¨å:
* 对象头(Header)ï¼Mark wordï¼ç±»åæéåæ°ç»é¿åº¦
* å®ä¾æ°æ®(Instance Data)
* 对é½å¡«å
(Padding)ï¼ä»¥8åè对é½
对象头ä¸ä¸è¬å
å«ä¸¤ä¸ªé¨å:
* æ è®°å Mark Wordï¼å ç¨ä¸ä¸ªæºå¨åï¼64ä½èææºæ¯8åèãå
æ¬ éä¿¡æ¯ï¼GCï¼hashcode
* ç±»åæé å ç¨ä¸ä¸ªæºå¨åï¼ä¹å°±æ¯8个åèã妿å å
åå°äº32GBï¼JVMé»è®¤ä¼å¼å¯æéå缩ï¼ååªå ç¨4个åèã
* å¦ææ¯æ°ç»ï¼å¯¹è±¡å¤´ä¸è¿ä¼å¤åºä¸ä¸ªé¨å: æ°ç»é¿åº¦ï¼intå¼ï¼å ç¨4åèã
å¯ä»¥æ¥çç å·¥å
·: JOL=Java Object Layout
䏾便¥è¯´ï¼ä¸é¢ç `MyOrder` ç±»çæ¯ä¸ªå¯¹è±¡ä¼å ç¨40个åèã
```java
public class MyOrder{
private long orderId;
private String userId = "a-long-user-id";
private byte state;
private long createMillis;
}
```
è®¡ç®æ¹å¼ä¸º:
* 对象头å ç¨12åèï¼Mark Word 8åèï¼æéå缩åå ç¨4个åè
* æ¯ä¸ªlongç±»åçåæ®µå ç¨8åèï¼2个longåæ®µå ç¨16åèã
* String ç±»åä¿åçå¼ç¨ï¼é»è®¤å¼å¯æéå缩ï¼å ç¨4 个åè
* byte åæ®µå ç¨1个åèã
以ä¸å计 33åèï¼æ8åè对é½ï¼å ä¸7 åè对é½å¡«å
ï¼åå®é
å ç¨40个åèã
## GC
### Default gc for Java different version
`java -XX:+PrintFlagsFinal -version | grep Use | grep GC | grep true` æ¥çé»è®¤ä½¿ç¨ç GC
| version | GC |
| ------------- | -------------------- |
| Java 9 ~ 17 | G1 garbage collector |
| Java 8 server | parallel collector |
| Java 8 client | serial collector |
| Java 7 server | parallel collector |
| Java 7 client | serial collector |
### GC éå
ååé = ä¸å¡ä»£ç æ¶é´ /ï¼ä¸å¡ä»£ç æ¶é´ + å徿¶éæ¶é´ï¼
交äºå¼åºç¨ï¼ä¿è¯åé¡¿æ¶é´ 300ms æ
åµä¸å°½å¯è½ å¢å åå
常è§åºç¨ï¼éè¦å¨ä¿è¯æå¤§ååéçæ
åµä¸ å°½å¯è½åå°åé¡¿æ¶é´
éæ©æ£ç¡®ç GC ç®æ³ï¼å¯ä¸å¯è¡çæ¹å¼å°±æ¯å»å°è¯ï¼å¹¶æ¾åºä¸åççå°æ¹ï¼ä¸è¬æ§çæå¯¼ååï¼
* 妿èèååä¼å
ï¼CPU å°½éé½ç¨äºå¤çä¸å¡ï¼ç¨ Parallel GCï¼
* 妿èèæéçä½å»¶è¿ï¼ä¸æ¯æ¬¡ GC æ¶é´å°½éçï¼ç¨ CMS GCï¼
* 妿å è¾å¤§ï¼åæ¶å¸ææ´ä½æ¥çå¹³å GC æ¶é´å¯æ§ï¼ä½¿ç¨ G1 GCã
对äºå
å大å°çèéï¼
* ä¸è¬ 4G 以ä¸ï¼ç®æ¯æ¯è¾å¤§ï¼ç¨ G1 GC çæ§ä»·æ¯è¾é«ã
* ä¸è¬è¶
è¿ 8Gï¼æ¯å¦ 16G-64G å
åï¼é常æ¨èä½¿ç¨ G1 GCã
* æ´å¤§å
åæè
ä½å»¶è¿è¦æ±é常èå»ï¼ç¨ ZGC ã
ç¹å«å°ï¼OpenJDK 11䏿¨èä½¿ç¨ G1 è䏿¯ ZGCï¼16+çæ¬æ¨èï¼ã
### G1
åç§ GC åççæ¶æº
* Young GCï¼å¨ Young åºæ»¡äº/åé
å
åå¤±è´¥çæ¶åï¼åæ¶ Young åºçå å
åã
* Mixed GCï¼å¨ Young åºæ»¡äºä¸ Old åºè¾¾å°ä¸å®æ¯ä¾æ¶ï¼åæ¶ Young åº+é¨å Old çå å
åã
* Full GCï¼å¨å å
åæ»¡äºçæ¶åï¼å¯å¨ Full GCï¼å°è¯åæ¶æ´ä¸ªå å
åã
### ZGC - JDK 11
[Z Garbage Collector](https://wiki.openjdk.java.net/display/zgc/Main)
[æ°ä¸ä»£åå¾åæ¶å¨ZGCçæ¢ç´¢ä¸å®è·µ - ç¾å¢ææ¯å¢é](https://tech.meituan.com/2020/08/06/new-zgc-practice-in-meituan.html)
goals
* Pause times do not exceed 10ms
* Pause times do not increase with the heap or live-set size
* Handle heaps ranging from a few hundred megabytes to multi terabytes in size
At a glance, ZGC is:
* Concurrent
* Region-based
* Compacting
* NUMA-aware
* Using colored pointers
* Using load barriers
æ±åç½è¡£æ¬è¡£ æ¥å¤©çæè¾¹ [Javaç¨åºåçè£å
ï¼å¬R大论JDK11çZGC](https://mp.weixin.qq.com/s/KUCs_BJUNfMMCO1T3_WAjw)
> R大: 䏿 记对象çä¼ ç»ç®æ³ç¸æ¯ï¼ZGC卿éä¸åæ è®°ï¼å¨è®¿é®æéæ¶å å
¥Load Barrierï¼è¯»å±éï¼ï¼æ¯å¦å½å¯¹è±¡æ£è¢«GCç§»å¨ï¼æéä¸çé¢è²å°±ä¼ä¸å¯¹ï¼è¿ä¸ªå±éå°±ä¼å
ææéæ´æ°ä¸ºææå°ååè¿åï¼ä¹å°±æ¯ï¼æ°¸è¿åªæåä¸ªå¯¹è±¡è¯»åæ¶ææ¦ç被åéï¼èä¸åå¨ä¸ºäºä¿æåºç¨ä¸GCä¸è´èç²æ´æ´ä½çStop The Worldã
ZGCçå
«å¤§ç¹å¾
1. ææé¶æ®µå ä¹é½æ¯å¹¶åæ§è¡ç
è¿éçå¹¶å(Concurrent)ï¼è¯´çæ¯åºç¨çº¿ç¨ä¸GC线ç¨é½å¤´å¹¶è¿ï¼äºä¸æ·»å µã
说å ä¹ï¼å°±æ¯è¿æä¸ä¸ªé常çæçSTWçé¶æ®µï¼æä»¥ZGC并䏿¯Zero Pause GCå¦
2. å¹¶åæ§è¡çä¿è¯æºå¶ï¼å°±æ¯ Colored Pointer å Load Barrier
Colored Pointer ä»64ä½çæéä¸ï¼åäºå ä½åºæ¥è¡¨ç¤ºFinalizableãRemappedãMarked1ãMarked0ã æä»¥å®ä¸æ¯æ32使éä¹ä¸æ¯æå缩æéï¼ ä¸å ç大尿¯æ 8MB to 16TB
3. åG1䏿 ·ååRegionï¼ä½æ´å çµæ´»
4. åG1䏿 ·ä¼åCompactingï¼å缩
ç²ç¥äºå ååå°è¿ä¸æ³¢åæ¶æµç¨ï¼å°é¶æ®µé½è¢«ç¥è¿äºå:
4.1. Pause Mark Start ï¼åå§åé¡¿æ è®°
4.2. Concurrent Mark ï¼å¹¶åæ è®°
4.3. Relocate ï¼ ç§»å¨å¯¹è±¡
4.4. Remap ï¼ ä¿®æ£æé
ä¸ä¸ä¸ªé¶æ®µçRemapï¼åä¸ä¸ä¸ªé¶æ®µçMarkæ¯æ··æå¨ä¸èµ·å®æçï¼è¿æ ·é叏髿ï¼çå´äºéå¤éå对象å¾çå¼éã
5. 没æG1å å
åçRemember Setï¼æ²¡æWrite Barrierçå¼é
6. æ¯æNumaæ¶æ
ç°å¨å¤CPUææ§½çæå¡å¨é½æ¯Numaæ¶æ
7. å¹¶è¡
8. å代
没å代ï¼åºè¯¥æ¯ZGCå¯ä¸çå¼±ç¹äº. æä»¥R大说ZGCçæ°´å¹³ï¼å¤äºAZulæ©æçPauselessGC ä¸ å代çC4ç®æ³ä¹é´ ï¼ C4å¨ä»£ç éå°±å«GPGCï¼Generational Pauseless GCã
å代忬æ¯å 为most object die youngçå设ï¼è让æ°ç代åèç代使ç¨ä¸åçGCç®æ³ãä½C4å·²ç»æ¯å
¨ç¨å¹¶åç®æ³äºï¼ä¸ºä»ä¹è¿è¦å代å¢ï¼
R大说ï¼å 为å代çC4è½æ¿åç对象åé
é度(Allocation Rate)ï¼ å¤§æ¦æ¯åå§PGCç10åã
## Javaé®é¢ææ¥å·¥å
·ç®±
### [Arthas](https://github.com/alibaba/arthas)
[Quick Start](https://alibaba.github.io/arthas/quick-start.html)
download: `wget https://alibaba.github.io/arthas/arthas-boot.jar`
startup: `java -jar arthas-boot.jar`
æ¥çåéå¼
[watch](https://arthas.aliyun.com/doc/en/watch.html) to view the return object and parameters
`watch Demo$Counter method {params,returnObj}`
`watch com.company.EnvironmentEnum isAbroad {params,returnObj} -x 3` more detail `-x`
`watch com.company.Service method {params,returnObj} "params[0]==1 && params[1]==new java.sql.Timestamp(1572424327000L)" -x 3`
`watch com.company.Service method "{params[0],throwExp}" -e -x 2` Check exceptions
æ¥çèæ¶
[trace](https://alibaba.github.io/arthas/trace.html) æ¹æ³å
é¨è°ç¨è·¯å¾ï¼å¹¶è¾åºæ¹æ³è·¯å¾ä¸çæ¯ä¸ªèç¹ä¸èæ¶
trace Demo$Counter getFactoryInfo '#cost>10' -n 1
`#cost > 10` åªä¼å±ç¤ºèæ¶å¤§äº10msçè°ç¨è·¯å¾
`-n` åæ°æå®ææç»æç次æ°
é»è®¤æ
åµä¸ï¼traceä¸ä¼å
å«jdkéç彿°è°ç¨ï¼å¦æå¸ætrace jdkéç彿°ï¼éè¦æ¾å¼è®¾ç½®`--skipJDKMethod false`ã
`trace -E com.test.ClassA|org.test.ClassB method1|method2|method3` ç¨æ£å表å¹é
è·¯å¾ä¸çå¤ä¸ªç±»å彿°ï¼ä¸å®ç¨åº¦ä¸è¾¾å°å¤å±traceçææ
sc Demo$Counter
#### [thread â Arthas 3.6.2 ææ¡£](https://arthas.aliyun.com/doc/thread.html)
`thread -n 3` å±ç¤ºå½åæå¿çåN个线ç¨å¹¶æå°å æ
`thread id`, æ¾ç¤ºæå®çº¿ç¨çè¿è¡å æ
`thread -b`, æ¾åºå½åé»å¡å
¶ä»çº¿ç¨ç线ç¨
`thread âstate` ï¼æ¥çæå®ç¶æç线ç¨
#### ognl
[ognl Arthasçä¸äºç¹æ®ç¨æ³ææ¡£è¯´æ #71](https://github.com/alibaba/arthas/issues/71)
```sh
# å°ç»ææname屿§æå½±ï¼
watch com.taobao.container.Test test "params[0].{ #this.name }"
# ææ¡ä»¶è¿æ»¤ï¼
watch com.taobao.container.Test test "params[0].{? #this.name == null }" -x 2
# è¿æ»¤åç»è®¡ï¼
watch com.taobao.container.Test test "params[0].{? #this.age > 10 }.size()" -x 2
# æ¥ç第ä¸ä¸ªåæ°çsizeï¼
watch com.taobao.container.Test test "params[0].size()"
# 夿å符串ç¸ç æ¯å¦ç¬¬ä¸ä¸ªåæ°æ¯Stringç±»åï¼
watch com.demo.Test test 'params[0]=="xyz"'
# 夿longå
watch com.demo.Test test 'params[0]==123456789L'
# åæ¶å¤æä¸¤ä¸ªå¼
watch com.demo.Test test 'params[0]==1L,params[0]=="xyz"'
```
#### Demo
[é¿éå·´å·´é®é¢ææ¥ç¥å¨Arthas使ç¨å®è·µ](https://mp.weixin.qq.com/s?__biz=MzI3NzE0NjcwMg==&mid=2650122813&idx=1&sn=3e419623e06cfc7900929bb6e88bcd24&chksm=f36bb71cc41c3e0a4fb7420498839af553db3073a4e02c5c67eca8d6e0f5d1f916673cb41d37&mpshare=1&scene=23&srcid=1216OroF3DROBapRZwxoMpkF#rd)
#### åç
attachï¼jdk1.6æ°å¢åè½ï¼éè¿attachæºå¶ï¼å¯ä»¥å¨jvmè¿è¡ä¸ï¼éè¿pidå
³èåºç¨
instrumentï¼jdk1.5æ°å¢åè½ï¼éè¿instrumentä¿ç§°javaagentææ¯ï¼å¯ä»¥ä¿®æ¹jvmå è½½çåèç
ç¶å arthas åå
¶ä»è¯æå·¥å
·ä¸æ ·ï¼é½æ¯å
éè¿attach龿¥ä¸ç®æ åºç¨ï¼éè¿instrumentå¨æä¿®æ¹åºç¨ç¨åºçåèç è¾¾å°ä¸éå¯åºç¨èçæ§åºç¨çç®ç
### java.net.SocketException å¼å¸¸
[understanding_some_common_socketexceptions_in_java3](https://www.ibm.com/developerworks/community/blogs/738b7897-cd38-4f24-9f05-48dd69116837/entry/understanding_some_common_socketexceptions_in_java3?lang=en)
[java.net.SocketException å¼å¸¸](http://developer.51cto.com/art/201003/189724.htm)
1. java.net.SocketException: Broken pipe (UNIX)
A broken pipe error is seen when the remote end of the connection is closed gracefully.
Solution: This exception usually arises when the socket operations performed on either ends are not sync'ed.
2. java.net.SocketException: reset by peer. This error happens on server side
3. java.net.SocketException: Connection reset. This error happens on client side
This exception appears when the remote connection is unexpectedly and forcefully closed due to various reasons like application crash, system reboot, hard close of remote host. Kernel from the remote system sends out a packets with RST bit to the local system. The local socket on performing any SEND (could be a Keep-alive packet) or RECEIVE operations subsequently fail with this error. Certain combinations of linger settings can also result in packets with RST bit set.
### [é«CPUå ç¨åæ](http://www.blogjava.net/hankchen/archive/2012/05/09/377735.html)
ä¸ä¸ªåºç¨å ç¨CPUå¾é«ï¼é¤äºç¡®å®æ¯è®¡ç®å¯éååºç¨ä¹å¤ï¼é常åå 齿¯åºç°äºæ»å¾ªç¯
1. `top -H`
2. æ¾å°å
·ä½æ¯CPUé«å ç¨ççº¿ç¨ `ps -mp -o THREAD,tid,time,rss,size,%mem`
3. å°éè¦ç线ç¨ID转æ¢ä¸º16è¿å¶æ ¼å¼ `printf "%x\n" tid`
4. æå°çº¿ç¨çå æ ä¿¡æ¯ `jstack PID | grep tid -A 30`
#### checklist from linux to application process
1. `top` çåºè¿ç¨ pid为 12666 çjavaè¿ç¨å ç¨äºè¾å¤çcpuèµæº
2. `top -Hp 12666` æ¥ç该è¿ç¨ä¸å线ç¨çCPUèµæº, å¯ä»¥æ¾å°å èµæºè¾å¤ç 线ç¨pid 为 12830 (12830 ç¨ 16 è¿å¶è¡¨ç¤ºä¸º 0x321e)
3. `jstack 12666 | grep nid=0x321e` æ¥çå½åjavaè¿ç¨çå æ ç¶æ
### å
åæ£æ¥æ¥éª¤
[è®°ä¸æ¬¡å
åå©ç¨çé®é¢ææ¥](https://mp.weixin.qq.com/s/0E6GxkCnuT8lpReeoeCbHg)
æ¥çjava线ç¨å¨å
åå¢é¿æ¶çº¿ç¨æ° `jstack PID | grep 'java.lang.Thread.State' | wc -l` æè
`cat /proc/pid/status | grep Thread`
ç¨pmapæ¥çè¿ç¨å
çå
å `RSS` æ
åµï¼è§å¯javaçheapåstackå¤§å° `pmap -x pid |less`
使ç¨gdbè§å¯å
ååéçå
容ï¼åç°é颿ä¸äºæ¥å£çè¿åå¼ãmcçè¿åå¼ãè¿æä¸äºç±»åçç `gdb: dump memory /tmp/memory.bin 0x7f6b38000000 0x7f6b38000000+65535000`
`hexdump -C /tmp/memory.bin` æ `strings /tmp/memory.bin |less`
ç¨straceåltraceæ¥æ¾mallocè°ç¨
#### Native Memory Tracking (NMT)
* java8 ç»HotSpot VMå¼å
¥äº NMT ç¹æ§ï¼å¯ä»¥ç¨äºè¿½è¸ªJVMçå
é¨å
å使ç¨
* Enable NMT `-XX:NativeMemoryTracking=[off | summary | detail]`
* Optionally print memory usage when the application terminates `-XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics`
* Use jcmd to Access NMT Data `jcmd VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB]`
* [Oracle Technology Network - Native Memory Tracking](https://docs.oracle.com/javase/8/docs/technotes/guides/vm/nmt-8.html)
* [Java Platform, Standard Edition Troubleshooting Guide - 2.7 Native Memory Tracking](https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html)
* 使ç¨`-XX:NativeMemoryTracking=summary`å¯ä»¥ç¨äºå¼å¯NMTï¼å
¶ä¸è¯¥å¼é»è®¤ä¸ºoffï¼å¯ä»¥è®¾ç½®summaryãdetailæ¥å¼å¯ï¼å¼å¯çè¯ï¼å¤§æ¦ä¼å¢å 5%-10%çæ§è½æ¶èï¼ä½¿ç¨-XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatisticså¯ä»¥å¨jvm shutdownçæ¶åè¾åºæ´ä½çnative memoryç»è®¡ï¼å
¶ä»çå¯ä»¥ä½¿ç¨`jcmd pid VM.native_memory`ç¸å
³å½ä»¤è¿è¡æ¥çãdiffãshutdownç
* æ´ä¸ªmemory主è¦å
å«äºJava HeapãClassãThreadãCodeãGCãCompilerãInternalãOtherãSymbolãNative Memory TrackingãArena Chunkè¿å é¨åï¼å
¶ä¸ `reserved` 表示åºç¨å¯ç¨çå
å大å°ï¼`committed` 表示åºç¨æ£å¨ä½¿ç¨çå
å大å°
* [èèHotSpot VMçNative Memory Tracking](https://cloud.tencent.com/developer/article/1406522)
Create a baseline and get differences over time
* `jcmd VM.native_memory baseline`
* `jcmd VM.native_memory detail.diff`
#### jemalloc æ¥çå å¤å
å anon
[jemalloc-5.3.0.tar.bz2](https://github.com/jemalloc/jemalloc/releases/download/5.3.0/jemalloc-5.3.0.tar.bz2)
* [native-jvm-leaks](https://github.com/jeffgriffith/native-jvm-leaks )
* [Use Case: Leak Checking](https://github.com/jemalloc/jemalloc/wiki/Use-Case:-Leak-Checking )
* [Debugging Java Native Memory Leaks](http://www.evanjones.ca/java-native-leak-bug.html )
* [Using jemalloc to get to the bottom of a memory leak](https://gdstechnology.blog.gov.uk/2015/12/11/using-jemalloc-to-get-to-the-bottom-of-a-memory-leak/ )
1. Install jemalloc following [native-jvm-leaks](https://github.com/jeffgriffith/native-jvm-leaks )
1. `./configure --enable-prof`
2. `make`
3. `sudo make install`
2. Starting your JVM with jemalloc `export LD_PRELOAD=/usr/local/lib/libjemalloc.so`
3. Configuring the profiler `export MALLOC_CONF=prof:true,lg_prof_interval:31,lg_prof_sample:17,prof_prefix:/path/to/jeprof/output/jeprof`
1. In this case `2^31` is about 2GB, so every 2GB of memory allocation, we'll get a .heap output file specified in the prof_prefix location
4. Run your program
5. Finding the needle `jeprof --show_bytes --gif $(which java) /path/to/jeprof/output/jeprof.*.heap > out.gif`
6. Compare two profile dumps: `jeprof --text $(which java) --base=jeprof.15139.16.i16.heap /jeprof.15139.27.i27.heap`
7. export to gif with `dot` which provided by
1. `sudo yum install -y graphviz`
2. `sudo yum --enablerepo=powertools install -y graphviz-gd`
#### gperf æ¥çå å¤å
å
* [Work with Google performance tools](http://alexott.net/en/writings/prog-checking/GooglePT.html )
* [perftoolsæ¥çå å¤å
åå¹¶è§£å³hbaseå
åæº¢åº](http://koven2049.iteye.com/blog/1142768 )
* [Gperftools Heap Leak Checker](https://gperftools.github.io/gperftools/heap_checker.html )
1. `export GPERF_HOME=/path/to/gperftools-2.7`
2. `export LD_PRELOAD=$GPERF_HOME/lib/libtcmalloc.so HEAPCHECK=normal`
3. `export HEAPPROFILE=/path/to/gperf/output.heap`
4. Run program `$GPERF_HOME/bin/pprof --text $(which java) $HEAPPROFILE.*.heap > gperf.output.text`
#### Valgrind
[The Valgrind Quick Start Guide](http://valgrind.org/docs/manual/quick-start.html )
`valgrind ls -l >& valgrind.log`
`valgrind --leak-check=yes myprog arg1 arg2`
#### perf
[perf Examples](http://www.brendangregg.com/perf.html )
[brendangregg/perf-tools](https://github.com/brendangregg/perf-tools )
1. `perf mem record sh jni.sh 1000000 10 leak` or attach a running process with `sudo perf record -g -p `
2. `perf mem report`
### CPUç¸å
³å·¥å
· bluedavy
[Javaé®é¢ææ¥å·¥å
·ç®±](https://mp.weixin.qq.com/s?__biz=MjM5MzYzMzkyMQ==&mid=2649826312&idx=1&sn=d28b3c91ef25a281256c6ccd2fafe0d3&mpshare=1&scene=23&srcid=1031nCrOjtP6QtlUYAL6QWso#rd )
碰å°ä¸äºCPUç¸å
³çé®é¢æ¶ï¼é常éè¦ç¨å°çå·¥å
·ï¼
`top (-H)` topå¯ä»¥å®æ¶çè§å¯cpuçææ ç¶åµï¼å°¤å
¶æ¯æ¯ä¸ªcoreçææ ç¶åµï¼å¯ä»¥æ´ææçæ¥å¸®å©è§£å³é®é¢ï¼-Håæå©äºçæ¯ä»ä¹çº¿ç¨é æçCPUæ¶èï¼è¿å¯¹è§£å³ä¸äºç®åçèCPUçé®é¢ä¼æå¾å¤§å¸®å©ã
`sar` saræå©äºæ¥çåå²ææ æ°æ®ï¼é¤äºCPUå¤ï¼å
¶ä»å
åï¼ç£çï¼ç½ç»ççåç§ææ é½å¯ä»¥æ¥çï¼æ¯ç«å¤§é¨åæ¶åé®é¢é½åçå¨è¿å»ï¼æä»¥ç¿»åå²è®°å½é常éè¦ã
`jstack` jstackå¯ä»¥ç¨æ¥æ¥çJavaè¿ç¨éç线ç¨é½å¨å¹²ä»ä¹ï¼è¿é常对äºåºç¨æ²¡ååºï¼é常æ
¢ççåºæ¯é½æä¸å°ç帮å©ï¼jstacké»è®¤åªè½çå°Javaæ ï¼èjstack -måå¯ä»¥çå°çº¿ç¨çJavaæ ånativeæ ï¼ä½å¦æJavaæ¹æ³è¢«ç¼è¯è¿ï¼åçä¸å°ï¼ç¶è大é¨åç»å¸¸è®¿é®çJavaæ¹æ³å
¶å®é½è¢«ç¼è¯è¿ï¼ã
`pstack` pstackå¯ä»¥ç¨æ¥çJavaè¿ç¨çnativeæ ã
`perf` ä¸äºç®åçCPUæ¶èçé®é¢é ç `top -H` + `jstack` é常è½è§£å³ï¼å¤æçè¯å°±éè¦åå©perfè¿ç§è¶
级å©å¨äºã
`cat /proc/interrupts` 乿以æè¿ä¸ªæ¯å 为对äºåå¸å¼åºç¨èè¨ï¼é¢ç¹çç½ç»è®¿é®é æçç½ç»ä¸æå¤çæ¶è乿¯ä¸ä¸ªå
³é®ï¼èè¿ä¸ªæ¶åç½å¡çå¤éå以ååè¡¡å°±é常éè¦äºï¼æä»¥å¦æè§å¯å°cpuçsiææ ä¸ä½ï¼é£ä¹ççinterruptså°±æå¿
è¦äºã
### å
åç¸å
³å·¥å
· bluedavy
碰å°ä¸äºå
åç¸å
³çé®é¢æ¶ï¼é常éè¦ç¨å°çå·¥å
·ï¼
`jstat` `jstat -gcutil`æ`-gc`ççæå©äºå®æ¶çgcçç¶åµï¼ä¸è¿æè¿æ¯æ¯è¾ä¹ æ¯çgc logã
`jmap` å¨éè¦dumpå
åççå
åé齿¯ä»ä¹çæ¶åï¼`jmap -dump`å¯ä»¥å¸®å©ä½ ï¼å¨éè¦å¼ºå¶æ§è¡fgcçæ¶åï¼å¨CMS GCè¿ç§ä¸å®ä¼äº§çç¢çåçGCä¸ï¼æ»æ¯ä¼æ¾å°è¿æ ·ççç±çï¼ï¼`jmap -histo:live`å¯ä»¥å¸®å©ä½ ï¼æ¾ç¶ï¼ä¸è¦é便æ§è¡ï¼ã
`gcore` ç¸æ¯`jmap -dump`ï¼å
¶å®ææ´å欢gcoreï¼å 为æè§å°±æ¯æ´å¿«ï¼ä¸è¿ç±äºæäºjdkçæ¬è²ä¼¼ågcoreé
åç䏿¯é£ä¹å¥½ï¼æä»¥é£ç§æ¶åè¿æ¯è¦ç¨jmap -dumpçã
`mat` æäºå
ådumpåï¼æ²¡æåæå·¥å
·çè¯ç¶å¹¶åµ
`btrace` å°æ°çé®é¢å¯ä»¥matåç´æ¥çåºï¼è夿°ä¼éè¦åç¨btraceå»å¨æè·è¸ªï¼btraceç»å¯¹æ¯Javaä¸çè¶
级ç¥å¨ï¼ä¸¾ä¸ªç®åä¾åï¼å¦æè¦ä½ 廿¥ä¸ä¸ä¸ªè¿è¡çJavaåºç¨ï¼åªéå¨å建ä¸ä¸ªæ°ç»å¤§å°>1000çArrayListï¼ä½ è¦æä¹åå¢ï¼å¨æbtraceçæ
åµä¸ï¼é£å°±æ¯ç§ç§éæå®çäºï¼:)
`gperf` Javaå å
çå
åæ¶èç¨ä¸é¢çä¸äºå·¥å
·åºæ¬è½æå®ï¼ä½å å¤å°±æ²å¬äºï¼ç®åçèµ·æ¥è¿æ¯åªægperfè¿ç®æ¯æ¯è¾å¥½ç¨çä¸ä¸ªï¼æè
ä»ç»éªä¸æ¥è¯´Direct ByteBufferãDeflater/Inflaterè¿äºæ¯å¸¸è§é®é¢ã
é¤äºä¸é¢çå·¥å
·å¤ï¼åæ ·å
åä¿¡æ¯çè®°å½ä¹é常éè¦ï¼å°±å¦æ¥å¿ä¸æ ·ï¼æä»¥åGCæ¥å¿æ¯ä¸å®è¦æå¼çï¼ç¡®ä¿å¨åºé®é¢åå¯ä»¥ç¿»æ¥GCæ¥å¿æ¥å¯¹ç
§æ¯å¦GCæé®é¢ï¼æä»¥å `-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:` è¿æ ·çåæ°å¿
é¡»æ¯å¯å¨åæ°çæ é
ã
#### Eclipse Memory Analyzer Tool (mat)
**Dominate**: An object x dominates an object y if every path in the object graph from the start (or the root) node to y must go through x.
**Dominator Tree** : A dominator tree is built out of the object graph. In the dominator tree each object is the immediate dominator of its children, so dependencies between the objects are easily identified.
**Shallow heap** is the memory consumed by one object.
**Retained set** of X is the set of objects which would be removed by GC when X is garbage collected.
**Retained heap** of X is the sum of shallow sizes of all objects in the retained set of X, i.e. memory kept alive by X.
### jvm log æ¶é´æ ¼å¼
* æå°ç»å¯¹æ¶é´ `-XX:+PrintGCDetails -XX:+PrintGCDateStamps`
* æå°ç¸å¯¹æ¶é´ `-XX:+PrintGCDetails -XX:+PrintGCTimeStamps`
* `-Xloggc` éè¦ä½¿ç¨ç»å¯¹è·¯å¾
* `-verbose:gc -Xloggc:/path/to/gc.%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps`
* `-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/hprof -XX:ErrorFile=/path/to/hs_err_pid%p.log`
* `java -XX:+PrintFlagsFinal -version` æå°å¹³å°é»è®¤å¼
[HotSpot VM Command-Line Options](https://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/clopts.html)
[Fatal Error Log](http://www.oracle.com/technetwork/java/javase/felog-138657.html#gbwcy)
### java 9 以䏿¥å¿æ ¼å¼
[OpenJDK 11 JVMæ¥å¿ç¸å
³åæ°è§£æä¸ä½¿ç¨_JKX_geekçå客-CSDNå客](https://blog.csdn.net/JKX_geek/article/details/104873302)
java -Xlog:help
é
ç½®ä»ä¹æ¥å¿å¯ä»¥è¢«è¾åº
`java -Xlog:all=warning`
è¾åºgcç¸å
³çæ¥å¿ `java -Xlog:gc`
ä»
è¾åºgc heapç¸å
³çæ¥å¿ `java -Xlog:gc+heap`
é
ç½®æ¥å¿è¾åºå°åªé
file=, ä¹å¯ä»¥ç´æ¥æå®æä»¶åï¼file=å¯ä»¥è¢«çç¥ `java -Xlog:gc*:file=/project/log/gc.log,filecount=50,filesize=50m`
示ä¾ï¼`java -Xlog:gc*=info:file=/project/log/gc.log,filecount=50,filesize=50m:time -version`
```sh
BASE_PATH=/data/gateway
SERVER_NAME=gateway-1.0.0
LOG_PATH=/data/log/gateway
# heapError åæ¾è·¯å¾
mkdir -p $LOG_PATH/log/gateway/hprof
HEAP_ERROR_PATH=$LOG_PATH/hprof
HEAP_DUMP="-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$HEAP_ERROR_PATH -XX:ErrorFile=$HEAP_ERROR_PATH/hs_err_pid%p.log"
# GC LOG
GC_LOG=-Xlog:gc*:file="$LOG_PATH/gc_pid%p.log":time,level,tags:filecount=100,filesize=100M
# JVM åæ°
#JAVA_OPS="-Xms512m -Xmx512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$HEAP_ERROR_PATH"
JAVA_OPS="-Xms1024m -Xmx1024m $HEAP_DUMP $GC_LOG"
CONFIG="--spring.config.location=file:$BASE_PATH/application.yaml"
nohup $JAVA_HOME/bin/java -server $JAVA_OPS $JAVA_AGENT -jar $BASE_PATH/$SERVER_NAME.jar $CONFIG > nohup.out 2>&1 &
# Linux
mkdir -p log/hprof
java -server \
-Xms1024m \
-Xmx1024m \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=log/gateway/hprof \
-XX:ErrorFile=log/gateway/hprof/hs_err_pid%p.log \
-Xlog:gc*:file=log/gateway/gc_pid%p.log:time,level \
-jar gateway-1.0.0.jar \
--spring.config.location=file:resources/application.yaml
```
windows java gc æ¥å¿
```bat
@REM java "-Djava.io.tmpdir=tmp" -jar !latestFile! --spring.config.location=application.yml > log.txt 2>&1
if not exist "log\hprof" mkdir "log\hprof"
java -server ^
-Djava.io.tmpdir="tmp" ^
-Xms15g -Xmx15g ^
-XX:+HeapDumpOnOutOfMemoryError ^
-XX:HeapDumpPath="log/hprof/" ^
-XX:ErrorFile="log/hprof/hs_err_pid%%p.log" ^
-Xlog:gc*:file="log/gc_pid%%p.log":time,level,tags:filecount=100,filesize=100M ^
-XX:+AlwaysPreTouch ^
-jar $BASE_PATH/$SERVER_NAME.jar ^
--spring.config.location=file:application.yml > log.txt 2>&1
```
#### å¨æä¿®æ¹JVMæ¥å¿çº§å«
éè¿ jcmd å¨æä¿®æ¹ JVM æ¥å¿é
ç½®ï¼ ä¸»è¦å½ä»¤æ¯VM.logï¼ å设æä»¬ç JVM è¿ç¨æ¯22,
* æ¥çå½ä»¤æ ¼å¼ `jcmd 22 VM.log`
* æ¥çå½åæ¥å¿åæ°é
ç½® `jcmd 22 VM.log list`
* 让æ¥å¿å¦èµ·ä¸ä¸ªæä»¶è¾åº `jcmd 22 VM.log rotate`
* å
³éæææ¥å¿ï¼å¹¶æ¸
çæ¥å¿ç¸å
³åæ° `jcmd 22 VM.log disable`
* æ°å¢æ¥å¿é
ç½®è¾åº `jcmd 22 VM.log output=/project/core/log/gc.log output_options="filecount=50,filesize=100M" decorators="utctime,level,tags" what="gc*=debug"`
* ä¿®æ¹æ¥å¿é
ç½®è¾åº ä¿æä¸ç°æçæä¸ªoutputä¸è´ï¼å°±æ¯ä¿®æ¹é
ç½®ï¼ä½æ¯ output_options åªè¦è®¾å®äºï¼å°±ä¸è½æ¹ï¼åªè½éè¿ disable å
³éæææ¥å¿ä¹åéæ°è®¾ç½®ã
* ä¿®æ¹é
置级å«ä¸ºinfo: `jcmd 22 VM.log output=/project/core/log/gc.log what="gc*=info"`
### ClassLoaderç¸å
³å·¥å
·
ä½ä¸ºJavaç¨åºåï¼ä¸ç¢°å°ClassLoaderé®é¢é£åºæ¬æ¯ä¸å¯è½çï¼å¨ææ¥æ¤ç±»é®é¢æ¶ï¼æå¥½åçè¿æ¯`-XX:+TraceClassLoading`ï¼æè
妿ç¥éæ¯ä»ä¹ç±»çè¯ï¼æçå»ºè®®å°±æ¯æææä¼è£
è½½çlibç®å½éçjarç¨`jar -tvf *.jar`è¿æ ·çæ¹å¼æ¥ç´æ¥æ¥çå²çªçclassï¼åä¸è¡çè¯å°±è¦å¼å¤btraceç¥å¨å»è·è¸ªClassloader.defineClassä¹ç±»çäºã
### å
¶ä»å·¥å
·
`jinfo` JavaæNå¤çå¯å¨åæ°ï¼Nå¤çé»è®¤å¼ï¼èä»»ä½ææ¡£é½ä¸ä¸å®åç¡®ï¼åªæç¨jinfo -flagsçå°çæé è°±ï¼çè³ä½ è¿å¯ä»¥ççjinfo -flagï¼ä½ ä¼åç°æ´å¥½ç©çã
`dmesg` ä½ çjavaè¿ç¨çªç¶ä¸è§äºï¼ ä¹è®¸å¯ä»¥è¯è¯dmesgå
ççã
`systemtap` æäºé®é¢ææ¥å°javaå±é¢æ¯ä¸å¤çï¼å½éè¦traceæ´åºå±çoså±é¢ç彿°è°ç¨çæ¶åï¼systemtapç¥å¨å°±å¯ä»¥æ´¾ä¸ç¨åºäºã
`gdb` æ´é«çº§çç©å®¶ä»¬ï¼æ¿çcore dumpå¯ä»¥ç¨gdbæ¥ææ¥æ´è¯¡å¼çä¸äºé®é¢ã
## Java Mermory check
### èææºçæ§å·¥å
·
[Troubleshooting Guide for Java SE 6 with HotSpot VM](http://www.oracle.com/technetwork/java/javase/memleaks-137499.html#gdysp)
* jps: èææºè¿ç¨ç¶åµå·¥å
· (Java Virtual Machine Process Status Tool)
* jstat: èææºç»è®¡ä¿¡æ¯å·¥å
· (Java Virtual Machine Statistics Monitoring Tool)
* jinfo: Javaé
置信æ¯å·¥å
·
* jmap: Javaå
åæ åå·¥å
· (Memory Map)
* jhat: èææºå 转å¨å¿«ç
§åæå·¥å
· (Java Heap Analysis Tool)
* jstack: Javaå æ è·è¸ªå·¥å
· (Stack Trace)
* HSDIS: JITçæä»£ç åæ±ç¼
* [jcmd](https://docs.oracle.com/en/java/javase/11/tools/jcmd.html) send diagnostic command requests to a running Java Virtual Machine (JVM)
* [jhsdb](https://docs.oracle.com/en/java/javase/11/tools/jhsdb.html): You use the jhsdb tool to attach to a Java process or to a core dump from a crashed Java Virtual Machine (JVM).
HSDB: `java -cp sa-jdi.jar sun.jvm.hotspot.HSDB`
[Serviceability in HotSpot](http://openjdk.java.net/groups/hotspot/docs/Serviceability.html)
#### jmap
ææ¥GCé®é¢å¿
ç¶ä¼ç¨å°çå·¥å
·ï¼jmapå¯ä»¥åè¯ä½ å½åJVMå
åå ä¸ç对象åå¸åå
¶å
³ç³»ï¼å½ä½ dumpå ä¹åå¯ä»¥ç¨å
ååæå·¥å
·, ä¾å¦ï¼Eclipse Memory Analyzer Toolï¼MATï¼ãVisualVMãjhatãjprofileçå·¥å
·æ¥çåæï¼ççæåªäºå¤§å¯¹è±¡ï¼æè
åªäºç±»çå®ä¾ç¹å«å¤ã
常ç¨ç¨æ³ï¼
强å¶FGCï¼-histo:live
dumpå ï¼-dump:[live],format=b,file=dump.bin
`$(ps -ef | grep applicationName | grep -v grep | awk '{print $2}')` è·åpid
æ¥çå代å
åå ç¨æ
åµï¼
* `jmap -heap [pid]`
* `jmap [pid]`
* `jmap -dump:format=b,file=/tmp/java_pid.hprof [pid]` å¯ä»¥å°å½åJavaè¿ç¨çå
åå ç¨æ
åµå¯¼åºæ¥
* `jmap -dump:live,format=b,file=/tmp/java_pid.hprof [pid]` å¯ä»¥å°å½åJavaè¿ç¨å活对象å¨å
åä¸å ç¨æ
åµå¯¼åºæ¥, `:live` ä¼è§¦å䏿¬¡Full GC
* `jmap -histo:live [pid] >a.log` æ¥çå½åJavaè¿ç¨åå»ºçæ´»è·å¯¹è±¡æ°ç®åå ç¨å
å大å°
* `jmap -histo $(ps -ef | grep applicationName | grep -v grep | awk '{print $2}') | head -20` top 20 å
åå ç¨
æµ
å ï¼Shallow Heapï¼: å¯¹è±¡çæµ
å æå®å¨å
åä¸ç大å°
ä¿çå ï¼Retained Heapï¼: æå½ç¹å®å¯¹è±¡è¢«åå¾åæ¶åå³å°éæ¾çå
å大å°, å 为 ä¿çå =å
åä¸çå¤§å° + ææå¯¹è±¡çå¼ç¨å¤§å°
#### jcmd
å¨JDK 1.7ä¹åï¼æ°å¢äºä¸ä¸ªå½ä»¤è¡å·¥å
·jcmdã宿¯ä¸ä¸ªå¤åè½å·¥å
·ï¼å¯ä»¥ç¨æ¥å¯¼åºå ï¼æ¥çjavaè¿ç¨ï¼å¯¼åºçº¿ç¨ä¿¡æ¯ï¼æ§è¡GCçã
jcmdæ¥æjmapç大é¨ååè½ï¼Oracle宿¹å»ºè®®ä½¿ç¨jcmd代æ¿jmap
[The jcmd Command](https://docs.oracle.com/en/java/javase/13/docs/specs/man/jcmd.html)
```sh
# jcmd pid help ååºè¯¥èææºæ¯æçææå½ä»¤
jcmd 8799 help
8799:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
help
For more information about a specific command use 'help '.
```
#### jhsdb
[jhsdb](https://docs.oracle.com/en/java/javase/11/tools/jhsdb.html)
JCMDãJHSDBååºç¡å·¥å
·ç对æ¯
| åºç¡å·¥å
· | JCMD | JHSDB |
| ----------------------- | --------------------------------- | ----------------------- |
| `jps -lm` | jcmd | N/A |
| `jmap -dump ` | `jcmd GC.heap_dump` | jhsdb jmap --binaryheap |
| `jmap-histo ` | `jcmd GC.class_histogram` | jhsdb jmap --histo |
| `jstack ` | `jcmd Thread.print` | jhsdb jstack --locks |
| `jinfo -sysprops ` | `jcmd VM.system_properties` | jhsdb info --sysprops |
| `jinfo -flags ` | `jcmd VM.flags` | jhsdb info --flags |
#### jstack
jstack å¯ä»¥åè¯ä½ å½åææJVMçº¿ç¨æ£å¨åä»ä¹ï¼å
æ¬ç¨æ·çº¿ç¨åèææºçº¿ç¨ï¼ä½ å¯ä»¥ç¨å®æ¥æ¥ççº¿ç¨æ ï¼å¹¶ä¸ç»åLockä¿¡æ¯æ¥æ£æµæ¯å¦åçäºæ»éåæ»éç线ç¨ã
å¦å¤å¨ç¨`top -H`çå°å ç¨CPUé常é«çpidæ¶ï¼å¯ä»¥è½¬æ¢æ16è¿å¶åå¨`jstack dump`åºæ¥çæä»¶ä¸æç´¢ï¼ççå°åºæ¯ä»ä¹çº¿ç¨å ç¨äºCPUã
#### jhat
`jhat -port 8080 /tmp/java_11211.hprof` æå¡å¯å¨åï¼è®¿é® [localhost](http://localhost:8080/)
#### jstat
å¯ä»¥åè¯ä½ å½åçGCæ
åµï¼å
æ¬GC次æ°ãæ¶é´ï¼å
·ä½çGCè¿å¯ä»¥ç»ågc.logæä»¶å»åæã
`jstat -gc pid 250 10`
`jstat -gcutil`
æ ¹æ®JVMçå
åå¸å±
* å å
å = 年轻代 + å¹´è代 + æ°¸ä¹
代
* 年轻代 = Edenåº + 两个Survivoråºï¼FromåToï¼
以ä¸ç»è®¡æ°æ®ååçå«ä¹ä¸º
S0CãS1CãS0UãS1Uï¼Survivor 0/1åºå®¹éï¼Capacityï¼å使ç¨éï¼Usedï¼
ECãEUï¼Edenåºå®¹éå使ç¨é
OCãOUï¼å¹´è代容éå使ç¨é
YGCãYGTï¼å¹´è½»ä»£GC次æ°åGCèæ¶
FGCãFGCTï¼Full GC次æ°åFull GCèæ¶
GCTï¼GCæ»èæ¶
PCãPUï¼æ°¸ä¹
代容éå使ç¨é
MC & MUï¼åä½ KBï¼Klass Metaspace以åNoKlass Metaspace两è
æ»å
±committedçå
åå¤§å° å 使ç¨é
CCSC & CCSUï¼åä½ KBï¼Klass Metaspaceçå·²ç»è¢«commitçå
åå¤§å° å 使ç¨é
#### jVisualVM
[VisualVM CPU Sampling](http://greyfocus.com/2016/05/visualvm-sampling/)
##### Sampling
Sampling on the other side works by periodically retrieving thread dumps from the JVM. In this case, the performance impact is minor (and constant since the thread dumps are retrieved using a fixed frequency) and thereâs no risk of introducing side effects. This process is a lot less intrusive and can also be performed quite reliably on remote applications (i.e. it could even be applied to production instances).
##### Profiling
Profiling involves instrumenting the entire application code or only some classes in order to provide runtime performance metrics to the profiler application. Since this involves changes to the application code, which are applied automatically by the profiler, it also means that there is a certain performance impact and risk of affecting the existing functionality.
##### Difference between âSelf Timeâ and âSelf Time (CPU)â
VisualVM reports two metrics related to the duration, but there is a significant difference between them:
* self time - counts the total time spent in that method, including the amount of time spent on locks or other blocking behaviour
* self time (cpu) - counts the total time spent in that method, excluding the amount of time the thread was blocked
#### [Interpretation of FieldType characters](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3)
[Z = boolean
[B = byte
[S = short
[I = int
[J = long
[F = float
[D = double
[C = char
[L = any non-primitives(Object)
#### Guidelines for Calculating Java Heap Sizing
Refer to Java Performance
##### Table 7-3 Guidelines for Calculating Java Heap Sizing
| Space | Command Line Option | Occupancy Factor |
| -------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| Java heap | -Xms and -Xmx | 3x to 4x old generation space occupancy after full garbage collection |
| Permanent Generation | -XX:PermSize -XX:MaxPermSize | 1.2x to 1.5x permanent generation space occupancy after full garbage collection |
| Young Generation | -Xmn 1x to 1.5x | old generation space occupancy after full garbage collection |
| Old Generation | Implied from overall Java heap size minus the young generation size | 2x to 3x old generation space occupancy after full garbage collection |
##### Refine Young Generation Size
* The old generation space size should be not be much smaller than 1.5x the live data size
* Young generation space size should be at least 10% of the Java heap size, the value specified as -Xmx and -Xms.
* When increasing the Java heap size, be careful not to exceed the amount of physical memory available to the JVM
### Other tools
#### [GCeasy](https://gceasy.io/)
Universal GC Log Analyzer: Upload GC Log File
Industry's first machine learning guided Garbage collection log analysis tool. GCeasy has in-built intelligence to auto-detect problems in the JVM & Android GC logs and recommend solutions to it.
#### [GCViewer](https://github.com/chewiebug/GCViewer)
GCViewer is a little tool that visualizes verbose GC output generated by Sun / Oracle, IBM, HP and BEA Java Virtual Machines.
#### [greys-anatomy](https://github.com/oldmanpushcart/greys-anatomy/wiki)
Greysæ¯ä¸ä¸ªJVMè¿ç¨æ§è¡è¿ç¨ä¸çå¼å¸¸è¯æå·¥å
·ï¼å¯ä»¥å¨ä¸ä¸æç¨åºæ§è¡çæ
åµä¸è½»æ¾å®æé®é¢ææ¥å·¥ä½ã
#### HouseMD
ä¸ä¸ªç±»ä¼¼äºBTraceçå·¥å
·ï¼ç¨äºå¯¹JVMè¿è¡æ¶çç¶æè¿è¡è¿½è¸ªåè¯æï¼ä½è
æ¯ä¸é´ä»¶å¢éçèç³ã
é常æä»¬ææ¥é®é¢å¾å¤æ¶åé½å¨ä»£ç ä¸å 个æ¥å¿ï¼ççæ¹æ³çåæ°ãè¿å弿¯ä¸æ¯æä»¬ææçï¼ç¶åç¼è¯æå
é¨ç½²éå¯åºç¨ï¼åå åéå°±è¿å»äºãHouseMDå¯ä»¥ç´æ¥è®©ä½ å¯ä»¥è¿½è¸ªå°æ¹æ³çè¿åå¼ååæ°ï¼ä»¥åè°ç¨æ¬¡æ°ãè°ç¨å¹³årtãè°ç¨æ ãçè³æ¯ç±»çæååéçå¼ãClasså è½½çè·¯å¾ã对åºçClassLoaderï¼é½å¯ä»¥ç¨ä¸è¡å½ä»¤ç»ä½ å±ç°åºæ¥ï¼å ªç§°ç¥å¨ã
æ´å¤çç¨æ³å¯ä»¥åè详ç»ç[WiKi](https://github.com/CSUG/HouseMD)
åå·å·åè¯ä½ ï¼å 为HouseMDæ¯åºäºåèç åææ¥åçï¼æä»¥ç论ä¸è¿è¡å¨JVMçè¯è¨é½å¯ä»¥ç¨å®ï¼å
æ¬Groovyï¼Clojureé½å¯ä»¥ã
## Java⢠Tutorials
[Java Documentation](http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html)
### Pausing Execution with `sleep`
`Thread.sleep` causes the current thread to suspend execution for a specified period
### Interrupts
An interrupt is an indication to a thread that it should stop what it is doing and do something else
线ç¨çthread.interrupt()æ¹æ³æ¯ä¸æçº¿ç¨ï¼å°ä¼è®¾ç½®è¯¥çº¿ç¨çä¸æç¶æä½ï¼å³è®¾ç½®ä¸ºtrueï¼ä¸æçç»æçº¿ç¨æ¯æ»äº¡ãè¿æ¯çå¾
æ°ç任塿æ¯ç»§ç»è¿è¡è³ä¸ä¸æ¥ï¼å°±åå³äºè¿ä¸ªç¨åºæ¬èº«ã
线ç¨ä¼ä¸æ¶å°æ£æµè¿ä¸ªä¸ææ 示ä½ï¼ä»¥å¤æçº¿ç¨æ¯å¦åºè¯¥è¢«ä¸æï¼ä¸ææ ç¤ºå¼æ¯å¦ä¸ºtrueï¼ã
#### å¤æçº¿ç¨æ¯å¦è¢«ä¸æ
使ç¨`Thread.currentThread().isInterrupted()`æ¹æ³ï¼å 为å®å°çº¿ç¨ä¸ææ 示ä½è®¾ç½®ä¸ºtrueåï¼ä¸ä¼ç«å»æ¸
é¤ä¸ææ 示ä½ï¼å³ä¸ä¼å°ä¸ææ 设置为falseï¼ï¼
ä¸è¦ä½¿ç¨`thread.interrupted()`ï¼è¯¥æ¹æ³è°ç¨åä¼å°ä¸ææ ç¤ºä½æ¸
é¤ï¼å³éæ°è®¾ç½®ä¸ºfalse
```java
//Thread.java
public void interrupt() //t.interrupt() ææt线ç¨ï¼è®¾ç½®tçº¿ç¨æç»æ å¿ä½f=trueï¼å¹¶ä¸æ¯ææçº¿ç¨çè¿è¡ï¼. å®ä¾æ¹æ³ï¼è®¾ç½®çº¿ç¨ä¸ææ å¿ï¼ææ°ä¸ä¸ï¼ä½ 该å¤çä¸ä¸ä¸æï¼
public boolean isInterrupted() //t.isInterrupted() æ¥è¯¢æææ å¿ä½æ¯å¦è¢«è®¾ç½®ï¼æ¯ä¸æ¯æ¾ç»è¢«ææè¿ï¼. å®ä¾æ¹æ³ï¼ææ²¡æäººææ°æï¼
public static boolean interrupted()//Thread.interrupted() æ¥çâå½åâçº¿ç¨æ¯å¦è¢«ææï¼å¦æè¢«ææï¼æ¢å¤æ å¿ä½. éææ¹æ³ï¼ææ²¡æäººææ°æï¼å½å线ç¨ï¼ï¼å¤ä½ï¼
```
#### åºå±ä¸æå¼å¸¸å¤çæ¹å¼
ä¸è¦å¨ä½ çåºå±ä»£ç éæè·`InterruptedException`å¼å¸¸åä¸å¤çï¼ä¼å¤çä¸å½ãå¦æä½ ä¸ç¥éæ`InterruptedException`å¼å¸¸åå¦ä½å¤çï¼é£ä¹ä½ æå¦ä¸å¥½ç建议å¤çæ¹å¼ï¼
1ãå¨catchåå¥ä¸ï¼è°ç¨`Thread.currentThread.interrupt()`æ¥è®¾ç½®ä¸æç¶æï¼å 为æåºå¼å¸¸å䏿æ 示ä¼è¢«æ¸
é¤ï¼ï¼è®©å¤çéè¿å¤æ`Thread.currentThread().isInterrupted()`æ 示æ¥å³å®æ¯å¦ç»æ¢çº¿ç¨è¿æ¯ç»§ç»ä¸å»ï¼åºè¯¥è¿æ ·åï¼
```java
try {
sleep(delay);
} catch (InterruptedException e) {
Thread.currentThread().isInterrupted();
}
```
2ãæè
ï¼æ´å¥½ç忳就æ¯ï¼ä¸ä½¿ç¨tryæ¥æè·è¿æ ·çå¼å¸¸
### Joins
The join method allows one thread to wait for the completion of another. If `t` is a `Thread` object whose thread is currently executing, `t.join();` causes the current thread to pause execution until t's thread terminates.
### `wait`
Always invoke wait inside a loop that tests for the condition being waited for. Don't assume that the interrupt was for the particular condition you were waiting for, or that the condition is still true.
Item 50 "Never invoke wait outside a loop" in Joshua Bloch's "Effective Java Programming Language Guide" (Addison-Wesley, 2001).
è¯¥æ¹æ³å±äºObjectçæ¹æ³ï¼waitæ¹æ³çä½ç¨æ¯**使å½åè°ç¨waitæ¹æ³æå¨é¨å(代ç å)ç线ç¨**忢æ§è¡ï¼å¹¶éæ¾å½åè·å¾çè°ç¨waitæå¨ç代ç åçéï¼å¹¶å¨å
¶ä»çº¿ç¨è°ç¨notifyæè
notifyAllæ¹æ³æ¶æ¢å¤å°ç«äºéç¶æ(䏿¦è·å¾éå°±æ¢å¤æ§è¡).
### Concurrent Collections
`BlockingQueue`, `ConcurrentMap`, `ConcurrentHashMap`, `ConcurrentNavigableMap`, `ConcurrentSkipListMap`
### Atomic Variables
`AtomicInteger`
## [çè§£Javaä¸çåç§å¼ç¨](http://www.importnew.com/17019.html)
Javaä¸å®é
䏿åç§å¼ºåº¦ä¸åçå¼ç¨ï¼ä»å¼ºå°å¼±å®ä»¬å嫿¯ï¼å¼ºå¼ç¨ï¼è½¯å¼ç¨ï¼å¼±å¼ç¨åèå¼ç¨
### 强å¼ç¨(Strong Reference)
å°±æ¯æä»¬ç»å¸¸ä½¿ç¨çå¼ç¨ï¼å
¶åæ³å¦ä¸ `StringBuffer buffer = new StringBuffer();`
### 软å¼ç¨ï¼Soft Referenceï¼
å½å
åä¸è¶³æ¶åå¾åæ¶å¨æä¼åæ¶è¿äºè½¯å¼ç¨å¯å°è¾¾ç对象ã
### å¼±å¼ç¨(Weak Reference)
å¼±å¼ç¨ç®åæ¥è¯´å°±æ¯å°å¯¹è±¡çå¨å
åçè½å䏿¯é£ä¹å¼ºçå¼ç¨ã使ç¨WeakReferenceï¼åå¾åæ¶å¨ä¼å¸®ä½ æ¥å³å®å¼ç¨çå¯¹è±¡ä½æ¶åæ¶å¹¶ä¸å°å¯¹è±¡ä»å
åç§»é¤ãå建弱å¼ç¨å¦ä¸
`WeakReference weakWidget = new WeakReference(widget)`
### èå¼ç¨ ï¼Phantom Referenceï¼
æä»¬ä¸å¯ä»¥éè¿getæ¹æ³æ¥å¾å°å
¶æåç对象ãå®çå¯ä¸ä½ç¨å°±æ¯å½å
¶æåçå¯¹è±¡è¢«åæ¶ä¹åï¼èªå·±è¢«å å
¥å°å¼ç¨éåï¼ç¨ä½è®°å½è¯¥å¼ç¨æåçå¯¹è±¡å·²è¢«éæ¯ã
èå¼ç¨ä½¿ç¨åºæ¯ä¸»è¦ç±ä¸¤ä¸ªãå®å
è®¸ä½ ç¥éå
·ä½ä½æ¶å
¶å¼ç¨ç对象ä»å
åä¸ç§»é¤ãèå®é
ä¸è¿æ¯Javaä¸å¯ä¸çæ¹å¼ãè¿ä¸ç¹å°¤å
¶è¡¨ç°å¨å¤ç类似å¾çç大æä»¶çæ
åµãå½ä½ ç¡®å®ä¸ä¸ªå¾çæ°æ®å¯¹è±¡åºè¯¥è¢«åæ¶ï¼ä½ å¯ä»¥å©ç¨èå¼ç¨æ¥å¤æè¿ä¸ªå¯¹è±¡åæ¶ä¹åå¨ç»§ç»å è½½ä¸ä¸å¼ å¾çãè¿æ ·å¯ä»¥å°½å¯è½å°é¿å
坿çå
åæº¢åºé误ã
第äºç¹ï¼èå¼ç¨å¯ä»¥é¿å
å¾å¤æææ¶çé®é¢ãfinalizeæ¹æ³å¯ä»¥éè¿å建强å¼ç¨æåå¿«è¢«éæ¯ç对象æ¥è®©è¿äºå¯¹è±¡éæ°å¤æ´»ã
## JVM è´å½é误æ¥å¿ï¼hs_err_pid.logï¼è§£è¯»
[JVM è´å½é误æ¥å¿ï¼hs_err_pid.logï¼è§£è¯»](https://www.raychase.net/1459) Posted on 06/27/2013 by åç«
[Exploring the Java âhs_err_pidâ File - DZone](https://dzone.com/articles/exploring-the-java-hs-err-pid-file)
[fastThread Analyze âhs_err_pidâ File tool](https://fastthread.io/ft-dashboard.jsp)
è´å½é误åºç°çæ¶åï¼JVM çæäº `hs_err_pid.log` è¿æ ·çæä»¶ï¼å
¶ä¸å¾å¾å
å«äºèææºå´©æºåå çéè¦ä¿¡æ¯ã
é»è®¤æ
åµä¸æä»¶æ¯å建å¨å·¥ä½ç®å½ä¸çï¼å¦ææ²¡æéå建çè¯ JVM ä¼å°è¯ææä»¶åå°/tmp è¿æ ·ç临æ¶ç®å½ä¸é¢å»ï¼ï¼å½ç¶ï¼æä»¶æ ¼å¼åè·¯å¾ä¹å¯ä»¥éè¿åæ°æå®ï¼æ¯å¦ï¼`java -XX:ErrorFile=/var/log/java/java_error%p.log`
è¿ä¸ªæä»¶å°å
æ¬ï¼
* 触åè´å½é误çæä½å¼å¸¸æè
ä¿¡å·ï¼
* çæ¬åé
置信æ¯ï¼
* 触åè´å½å¼å¸¸ç线ç¨è¯¦ç»ä¿¡æ¯åçº¿ç¨æ ï¼
* å½åè¿è¡ç线ç¨å表åå®ä»¬çç¶æï¼
* å çæ»æ¬ä¿¡æ¯ï¼
* å è½½çæ¬å°åºï¼
* å½ä»¤è¡åæ°ï¼
* ç¯å¢åéï¼
* æä½ç³»ç» CPU ç详ç»ä¿¡æ¯ã
é¦å
ï¼çå°çæ¯å¯¹é®é¢çæ¦è¦ä»ç»ï¼
```shell
# SIGSEGV (0xb) at pc=0x03568cf4, pid=16819, tid=3073346448
```
ä¸ä¸ªé颿çé误被 JRE æ£æµå°ï¼å
¶ä¸ï¼
* SIGSEGV æ¯ä¿¡å·åç§°
* 0xb æ¯ä¿¡å·ç
* pc=0x03568cf4 æçæ¯ç¨åºè®¡æ°å¨çå¼
* pid=16819 æ¯è¿ç¨å·
* tid=3073346448 æ¯çº¿ç¨å·
å¦æä½ å¯¹ JVM æäºè§£ï¼åºè¯¥ä¸ä¼å¯¹è¿äºä¸è¥¿éçã
æ¥ä¸æ¥æ¯ JRE å JVM ççæ¬ä¿¡æ¯ï¼
```shell
# JRE version: 6.0_32-b05
# Java VM: Java HotSpot(TM) Server VM (20.7-b02 mixed mode linux-x86 )
```
è¿è¡å¨ mixed 模å¼ä¸ã
ç¶åæ¯é®é¢å¸§çä¿¡æ¯ï¼
```shell
# Problematic frame:
# C [libgtk-x11-2.0.so.0+0x19fcf4] __float128+0x19fcf4
```
* Cï¼å¸§ç±»å为æ¬å°å¸§ï¼å¸§çç±»åå
æ¬ï¼
* Cï¼æ¬å° C 帧
* jï¼è§£éç Java 帧
* Vï¼èææºå¸§
* vï¼èææºçæçåæ ¹æ 帧
* Jï¼å
¶ä»å¸§ç±»åï¼å
æ¬ç¼è¯åç Java 帧
`libgtk-x11-2.0.so.0+0x19fcf4`ï¼åç¨åºè®¡æ°å¨ï¼pcï¼è¡¨è¾¾çå«ä¹ä¸æ ·ï¼ä½æ¯ç¨çæ¯æ¬å° so åº+åç§»éçæ¹å¼ã
## åèç
妿å®é
项ç®ä¸éè¦è¿è¡åºç¡çåèç æä½ï¼å¯ä»¥èèä½¿ç¨æ´å é«å±æ¬¡è§è§çç±»åºï¼ä¾å¦[Byte Buddy](https://bytebuddy.net/#/)çã