目錄
寫在前面
1、使用jmap了解系統運行時的記憶體區域
2、使用jmap了解系統運行時的物件分布
3、使用jmap生成堆記憶體轉儲快照
4、使用jhat在瀏覽器中分析堆轉出快照
5、案例實戰
5.1、模擬代碼的JVM引數設定
5.2、示例程式
5.3、通過jstat觀察程式的運行狀態
5.4、對JVM性能進行優化
寫在前面
jmap和jhat可以幫助我們觀察線上JVM中的物件分布,了解到你的系統平時運行程序中,到底哪些物件占據了主角位置,他們占據了多少記憶體空間,
1、使用jmap了解系統運行時的記憶體區域
2、使用jmap了解系統運行時的物件分布
他會按照各種物件占用記憶體空間的大小降序排列,把占用記憶體最多的物件放在最上面,
3、使用jmap生成堆記憶體轉儲快照
jmap -dump:live,format=b,file=dump.hprof PID
4、使用jhat在瀏覽器中分析堆轉出快照
jhat dump.hprof -port 7000
5、案例實戰
5.1、模擬代碼的JVM引數設定
接著我們會用一段程式來模擬出那種頻繁Full GC的一個場景,此時JVM引數如下所示:
-XX:NewSize=104857600 -XX:MaxNewSize=104857600 -XX:InitialHeapSize=209715200
-XX:MaxHeapSize=209715200 -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15
-XX:PretenureSizeThreshold=20971520 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
“-XX:PretenureSizeThreshold”,把大物件閾值修改為了20MB,避免我們程式里分配的大物件直接進入老年代,
5.2、示例程式
public class Demo {
public static void main(String[] args) throws Exception {
Thread.sleep(30000);
while(true) {
loadData();
}
}
public static void loadData() throws InterruptedException {
byte[] data = null;
for (int i = 0; i < 4; i++) {
data = new byte[10 * 1024 * 1024];
}
data = null;
byte[] data1 = new byte[10 * 1024 * 1024];
byte[] data2 = new byte[10 * 1024 * 1024];
byte[] data3 = new byte[10 * 1024 * 1024];
data3 = new byte[10 * 1024 * 1024];
Thread.sleep(1000);
}
}
大概意思其實就是,每秒鐘都會執行一次loadData()方法,他會分配4個10MB的陣列,但是都立馬成為垃圾,但是會有data1和data2 兩個10MB的陣列是被變數參考必須存活的,此時Eden區已經占用了六七十MB空間了,接著是data3變數依次指向了兩個10MB的數 組,這是為了在1s內觸發Young GC的,
5.3、通過jstat觀察程式的運行狀態
程式運行起來之后,突然在一秒內就發生了一次Young GC,這是為什么呢?
然后我們明顯看到在OU中多出來了30MB左右的物件,因此可以確定,在這次Young GC的時候,有30MB的物件存活了,此時因為Survivor區域放不下,所以直接進入老年代了,
很明顯每秒會發生一次Young GC,都會導致20MB~30MB左右的物件進入老年代,因為每次Young GC都會存活下來這么多物件,但是Survivor區域是放不下的,所以都會直接進入老年代,
對于YoungGC和FullGC的耗時?
18次Young GC,結果耗費了170毫秒,平均下來一次Young GC要5毫秒左右,但是9次Full GC才耗費10毫秒,平均下來一次Full GC才耗費1毫秒,這是為什么呢?
5.4、對JVM性能進行優化
-XX:NewSize=209715200 -XX:MaxNewSize=209715200 -XX:InitialHeapSize=31457280
-XX:MaxHeapSize=314572800 -XX:SurvivorRatio=2 -XX:MaxTenuringThreshold=15
-XX:PretenureSizeThreshold=20971520 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
在上述截圖里,大家可以清晰看到,每秒的Young gC過后,都會有20MB左右的存活物件進入Survivor,但是每個Survivor區都是50MB的大小,因此可以輕松容納,而且一般不會過50%的動態年齡判定的閾值,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/300838.html
標籤:其他
上一篇:Halcon影像測量
下一篇:Linux 行程(一)
