原文地址:http://www.javatang.comhtml
當服務器CPU100%的時候,經過定位佔用資源最大的線程定位到 VM Thread:java
"VM Thread" prio=10 tid=0x00007fbea80d3800 nid=0x5e9 runnable
這個時候須要使用 jstat -gc <pid> <period> <times>
命令查看gc的信息,顯示結果以下:
bash
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
64.0 64.0 0.0 0.0 332992.0 0.0 666304.0 73192.5 83968.0 83967.9 6893 17.576 6882 2705.923 2723.499
結果中每一個項目的含義能夠參考官方對jstat的文檔,簡單翻譯以下:服務器
- S0C: Young Generation第一個survivor space的內存大小 (kB).
- S1C: Young Generation第二個survivor space的內存大小 (kB).
- S0U: Young Generation第一個Survivor space當前已使用的內存大小 (kB).
- S1U: Young Generation第二個Survivor space當前已經使用的內存大小 (kB).
- EC: Young Generation中eden space的內存大小 (kB).
- EU: Young Generation中Eden space當前已使用的內存大小 (kB).
- OC: Old Generation的內存大小 (kB).
- OU: Old Generation當前已使用的內存大小 (kB).
- PC: Permanent Generation的內存大小 (kB)
- PU: Permanent Generation當前已使用的內存大小 (kB).
- YGC: 從啓動到採樣時Young Generation GC的次數
- YGCT: 從啓動到採樣時Young Generation GC所用的時間 (s).
- FGC: 從啓動到採樣時Old Generation GC的次數.
- FGCT: 從啓動到採樣時Old Generation GC所用的時間 (s).
- GCT: 從啓動到採樣時GC所用的總時間 (s).
JDK8的結果稍微有所不一樣,結果含義能夠參考:http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html。oracle
上面中的Young Generation、Permanent Generation和Old Generation等概念有一些混亂,這裏簡要的進行說明。簡單來講,JVM內存由堆(Heap)和非堆(Non-heap)內存組成,前者共運行在JVM之上的程序使用,後者供JVM本身使用。
優化
堆內存的組成以下:
spa
非堆內存由 Permanent Generation 和 Code Cache 兩部分組成:操作系統
-Xms
和 -Xmx
分別設置最小和最大堆內存-Xmn
設置,-XX:SurvivorRatio=m
設置 Eden和 兩個Survivor區的大小比值;-XX:NewRatio=n
設置 New Generation 和 Old Generation 的大小比值。非堆內存由 -XX:PermSize=n
和 -XX:MaxPermSize=n
分別設置最小和最大非堆內存大小線程
介紹完上面的概念以後,咱們再來看最上面的日誌信息,有兩個地方有問題:
一是FGC(徹底GC)的數量太大了,正常來講FGC應該佔整個GC(YGC+FGC)的1%到5%才正常,上面日誌上徹底GC的次數太多了;二是日誌中PU的值太大了,基本上已經達到設置的PC了,所以須要增大MaxPermSize的值。
不過這只是權宜之計,出現這麼大的非堆內存,確定什麼地方出現了問題,還須要進一步找到佔用內存的緣由,這也是後面文章所要說的。翻譯