一 查看基本jvm參數
1. 查對應的進程: jps -l
2. 查看設置過值的參數:jinfo -flags pid
3. 查看初始堆內存:jinfo -flag InitialHeapSize pid
4. 查看最大堆內存:jinfo -flag MaxHeapSize pid
5. 查看永久代:jinfo -flag PermSize pid
6. 查看最大永久代:jinfo -flag MaxPermSize pid
7. 查看年輕代初始內存:jinfo -flag NewSize pid
8. 查看年輕代最大內存:jinfo -flag MaxNewSize pid
9. 查看年輕代與年老代的比值:jinfo -flag NewRatio pid
10. 查看年輕代中Eden區與Survivor區的比值:jinfo -flag SurvivorRatio pid
11. 查看分代年齡:jinfo -flag MaxTenuringThreshold pid
12. 查看收集器
12.1 查看串行收集器:jinfo -flag UseSerialGC pid
12.2 查看並行收集器:jinfo -flag UseParallelGC pid
12.3 查看並行收集器:jinfo -flag UseParNewGC pid
12.4 查看並行收集器:jinfo -flag UseParallelOldGC pid
12.5 查看CMS回收器:jinfo -flag UseConcMarkSweepGC pid
12.6 查看G1回收器:jinfo -flag UseG1GC pid
13. 查看是否打印GC日誌:jinfo -flag PrintGCDetails pid
沒有打印
14. 打印jvm運行配置的參數:jmap -heap pid
二 調優重要參數設置
1設置最小堆和最大堆一樣
原因
空餘堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制,空餘堆內存大於70%時,JVM會減少堆直到-Xms的最小限制。因此服務器一般設置-Xms、-Xmx 相等以避免在每次GC後調整堆的大小。
操作(本機以idea作爲操作)
-Xms1024m
-Xmx1024m
2 設置收集器爲g1收集器
-XX:+UseG1GC
2.1 好處
-
並行性
- 回收期間,可以由多個GC線程同時工作,有效的利用多核的計算能力
-
併發性
- G1擁有與應用程序交替執行的能力,部分工作可以與應用程序同時執行,不會在整個回收期間完全阻塞應用程序。
-
分代GC
- G1兼顧了年輕代和老年代,相比較於其他的垃圾回收器,其他的收集器只能工作於年輕代或者老年代其中的一個,所以在這個方面和之前的收集器有所不同。
-
空間整理
- 在回收過程中會進行適當的對象移動,與CMS不同,只是簡單的標記清理對象,在若干次GC之後,CMS必須執行一次碎片整理,G1則是每次回收都會有效的複製對象,儘量減少空間碎片。
-
可預見性
- 由於分區的原因,G1可以只選取部分區域進行內存回收,可以縮小回收範圍,對於全局停頓有很好的掌控性。
2.2 概括
- JDK1.7中使用。
- 目標是爲了取代CMS回收器。
- 也分爲年輕代和老年代,任然是有eden區和survivor區。
- 不要求整個的eden區、年輕代或者老年代是連續的空間,使用的是一個分區算法。
2.3 案例
3 設置吞吐量大小/最大垃圾收集停頓時間
-XX:MaxGCPauseMillis=n
3.1 說明
- 設置最大垃圾收集停頓時間,如果無法滿足此時間,JVM會自動調整年輕代大小(堆內存年輕代比例,eden from to 比例),以滿足此在n值之內。
- 參考值:2000,具體的看業務,謹慎使用,不然服務器會崩潰
3.2 案例
4 堆佔用了多少比例的時候觸發GC
-XX:InitiatingHeapOccupancyPercent=n
4.1 說明
- 默認:n=45,對於這個值就觸發GC
- n=當前可以使用的堆內存*100/整個Java堆
- 可以使用的堆內存佔用了多少比例的時候觸發GC。默認佔用率是整個Java堆的45%
4.2 案例
5 設置新生代與老生代的大小比例
-XX:NewRatio=n
5.1 說明
- 設置新生代與老生代的大小比例
- 默認:2
5.2 案例
6 設置eden/survivor空間大小的比例
-XX:SurvivorRatio=n
6.1 說明
- 默認:8
6.2 案例
7 設置分代年齡
-XX:MaxTenuringThreshold=n
7.1 說明
- 默認: 15
7.2 案例
8 設置垃圾收集器在並行階段使用的線程數
-XX:ParallelGCThreads=n
8.1 說明
- 默認值:隨JVM運行的平臺不同而不同
8.2 案例
9 併發垃圾收集器使用的線程數量
-XX:ConcGCThreads=n
9.1 說明
- 默認值:隨JVM運行的平臺不同而不同
9.2 案例
10 設置堆內存保留爲假天花板的總量,以降低提升失敗的可能性
-XX:G1ReservePercent=n
10.1 說明
- 默認值:10
10.2 案例
11 指定每個region區的大小
-XX:G1HeapRegionSize=n
11.1 說明
- 使用G1時Java堆會被分爲大小統一的的區(region) ,該參數可以指定每個region區的大小
- 默認值:根據 heap size 算出最優解. 最小值爲 1Mb, 最大值爲 32Mb.
11.2 案例
三 VisualVM 工具的使用
##測試代碼
public class Demo2 {
private static final int _1MB = 1 * 1024 * 1024;
public static void main(String[] args) throws InterruptedException {
int size = 1000 * 10000;
int time = 1000;
byte[] a1 = null;
for (int i = 0; i < size; ) {
System.out.println("次數:" + ++i);
a1 = new byte[_1MB];
Thread.sleep(time);
}
}
}
vm配置
-Xms10M
-Xmx10M
-XX:+UseG1GC
-XX:NewRatio=2
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=10
###1 監視(CPU,堆,類,線程)
- 正常的堆,應該是鋸齒週期情況
###2 在出現OOME時生成堆
###3 內存 性能分析
- 可以查看哪些對象佔用了較多的內存
- 哪些對象存活的時間比較長
###4 CPU 性能分析
###5 抽樣器分析
###6 線程分析
###7 visual GC 分析(安裝插件)
###8 快照功能
- 生成任意個性能分析快照並保存到本地
- 可以離線進行性能分析
Profiler 快照
應用程序快照
###9 線程轉儲的生成與分析
對正在運行的本地應用程序生成線程轉儲,把活動線程的堆棧蹤跡打印出來,幫助我們瞭解線程運行的情況,診斷死鎖、應用程序癱瘓等問題。
###10 堆轉儲的生成與分析
- 可以看到摘要、類、實例數等信息以及通過OQL控制檯執行查詢語句功能。
- 堆轉儲的摘要包括轉儲的文件大小、路徑等基本信息,運行的系統環境信息,也可以顯示所有的線程信息。
四 生產oom分析案例
##4.1 問題描述
項目首頁,匿名無登陸,對首頁進行150個線程,8小時壓測,可以看到老年代一直在增加(visual gc),到某一時刻,直接oom,堆空間的圖不是矩形。
##4.2 解決方案(堆dump文件分析)
- 加載dump文件
- 分析自己寫的實體
- 雙擊進去
- 點就屬性中,非基本類型的,且是自己寫的實體屬性(CmsUserSite)
結論
說明CmsUserSite循環引用(a–>b–>a),循環引用造成內存溢出。
dump文件地址:
鏈接:https://pan.baidu.com/s/1ZtDGI8C-xUjwGK1nza56DQ
提取碼:67qt