自适应堆大小
在改進我們的測試平臺以改進Plumbr GC問題檢測器的同時 ,我最終編寫了一個小型測試用例,我認為這對于更廣泛的讀者來說可能很有趣。 我追求的目標是測試JVM在eden,survivor和Tenured空間之間如何分割堆方面的自適應性。
測試本身正在成批生成對象。 批處理每秒生成一次,每個批處理大小為500KB。 這些對象被引用五秒鐘,此后將刪除引用,并且該特定批處理中的對象可以進行垃圾收集。
該測試是使用ParallelGC在Mac OS X上的Oracle Hotspot 7 JVM上運行的,具有30MB的可用堆空間。 了解了平臺,我們可以預期JVM將使用以下堆配置啟動:
- JVM將以Young中的10MB和Tenured空間中的20MB開頭,因為沒有顯式配置,JVM將使用1:2的比率在Young和Tenured空間之間分配堆。
- 在我的Mac OS X中,在Eden和兩個Survivor空間之間進一步分配了10MB的年輕空間,分別為8MB和2x1MB。 同樣,這些是所使用的特定于平臺的默認值。
的確,當啟動測試并使用jstat在后臺進行窺視時,我們將看到以下內容,這證實了我們的餐巾紙估計:
My Precious:gc-pressure me$ jstat -gc 2533 1sS0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT 1024.0 1024.0 0.0 0.0 8192.0 5154.4 20480.0 0.0 21504.0 2718.9 0 0.000 0 0.000 0.000 1024.0 1024.0 0.0 0.0 8192.0 5502.1 20480.0 0.0 21504.0 2720.1 0 0.000 0 0.000 0.000 1024.0 1024.0 0.0 0.0 8192.0 6197.5 20480.0 0.0 21504.0 2721.0 0 0.000 0 0.000 0.000 1024.0 1024.0 0.0 0.0 8192.0 6545.2 20480.0 0.0 21504.0 2721.2 0 0.000 0 0.000 0.000 1024.0 1024.0 0.0 0.0 8192.0 7066.8 20480.0 0.0 21504.0 2721.6 0 0.000 0 0.000 0.000 1024.0 1024.0 0.0 0.0 8192.0 7588.3 20480.0 0.0 21504.0 2722.1 0 0.000 0 0.000 0.000從這里,我們還可以對即將發生的情況給出下一組預測:
- 伊甸園中的8MB內存將在16秒內填滿-請記住,我們每秒生成500KB的對象
- 在每一刻,我們都有大約2.5MB的活動對象-每秒生成500KB,并將對象的引用保持五秒鐘,這大約等于我們的數量
- 每當Eden滿時,次要GC都會觸發-這意味著我們應該每16秒左右看到一次次要GC。
- 在進行次要的GC之后,我們將過早地進行升級– Survivor空間只有1MB大小,而2.5MB的現場設置將無法容納我們的1MB Survivor空間中的任何一個。 因此,清潔伊甸園的唯一方法是將1.5MB(2.5MB-1MB)的不適合生存者的活動物體傳播到終身空間。
查看日志也使我們對這些預測充滿信心:
My Precious:gc-pressure me$ jstat -gc -t 2575 1s Time S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT 6.6 1024.0 1024.0 0.0 0.0 8192.0 4117.9 20480.0 0.0 21504.0 2718.4 0 0.000 0 0.000 0.0007.6 1024.0 1024.0 0.0 0.0 8192.0 4639.4 20480.0 0.0 21504.0 2718.7 0 0.000 0 0.000 0.000... cut for brevity ...14.7 1024.0 1024.0 0.0 0.0 8192.0 8192.0 20480.0 0.0 21504.0 2723.6 0 0.000 0 0.000 0.00015.6 1024.0 1024.0 0.0 1008.0 8192.0 963.4 20480.0 1858.7 21504.0 2726.5 1 0.003 0 0.000 0.00316.7 1024.0 1024.0 0.0 1008.0 8192.0 1475.6 20480.0 1858.7 21504.0 2728.4 1 0.003 0 0.000 0.003... cut for brevity ...29.7 1024.0 1024.0 0.0 1008.0 8192.0 8163.4 20480.0 1858.7 21504.0 2732.3 1 0.003 0 0.000 0.00330.7 1024.0 1024.0 1008.0 0.0 8192.0 343.3 20480.0 3541.3 21504.0 2733.0 2 0.005 0 0.000 0.00531.8 1024.0 1024.0 1008.0 0.0 8192.0 952.1 20480.0 3541.3 21504.0 2733.0 2 0.005 0 0.000 0.005... cut for brevity ...45.8 1024.0 1024.0 1008.0 0.0 8192.0 8013.5 20480.0 3541.3 21504.0 2745.5 2 0.005 0 0.000 0.00546.8 1024.0 1024.0 0.0 1024.0 8192.0 413.4 20480.0 5201.9 21504.0 2745.5 3 0.008 0 0.000 0.00847.8 1024.0 1024.0 0.0 1024.0 8192.0 961.3 20480.0 5201.9 21504.0 2745.5 3 0.008 0 0.000 0.008不是在16秒內,而是每15秒左右,垃圾收集就會啟動,清理Eden,并將約1MB的活動對象傳播到其中一個Survivor空間,并將剩余空間溢出到Old space。
到目前為止,一切都很好。 JVM確實表現出我們所期望的方式。 JVM監視了一段時間之后,有趣的部分開始了,并開始了解正在發生的事情。 在我們的測試案例中,這大約在90秒內發生:
My Precious:gc-pressure me$ jstat -gc -t 2575 1s Time S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT 94.0 1024.0 1024.0 0.0 1024.0 8192.0 8036.8 20480.0 8497.0 21504.0 2748.8 5 0.012 0 0.000 0.01295.0 1024.0 3072.0 1024.0 0.0 4096.0 353.3 20480.0 10149.6 21504.0 2748.8 6 0.014 0 0.000 0.01496.0 1024.0 3072.0 1024.0 0.0 4096.0 836.6 20480.0 10149.6 21504.0 2748.8 6 0.014 0 0.000 0.01497.0 1024.0 3072.0 1024.0 0.0 4096.0 1350.0 20480.0 10149.6 21504.0 2748.8 6 0.014 0 0.000 0.01498.0 1024.0 3072.0 1024.0 0.0 4096.0 1883.5 20480.0 10149.6 21504.0 2748.8 6 0.014 0 0.000 0.01499.0 1024.0 3072.0 1024.0 0.0 4096.0 2366.8 20480.0 10149.6 21504.0 2748.8 6 0.014 0 0.000 0.014 100.0 1024.0 3072.0 1024.0 0.0 4096.0 2890.2 20480.0 10149.6 21504.0 2748.8 6 0.014 0 0.000 0.014 101.0 1024.0 3072.0 1024.0 0.0 4096.0 3383.7 20480.0 10149.6 21504.0 2748.8 6 0.014 0 0.000 0.014 102.0 1024.0 3072.0 1024.0 0.0 4096.0 3909.7 20480.0 10149.6 21504.0 2748.8 6 0.014 0 0.000 0.014 103.0 3072.0 3072.0 0.0 2720.0 4096.0 323.0 20480.0 10269.6 21504.0 2748.9 7 0.016 0 0.000 0.016我們在這里看到的是JVM的驚人適應性。 在了解了應用程序的行為之后,JVM調整了幸存者空間的大小,使其足以容納所有活動對象。 現在,Young空間的新配置為:
- 伊甸園4MB
- 幸存者空間各3MB
此后,GC頻率增加–伊甸園現在減小了50%,而不是大約16秒,它現在大約填充了8秒左右。 但是好處也顯而易見,因為幸存者空間現在足夠大,可以在任何給定時間容納活動物。 再加上沒有對象的生存時間超過一個較小的GC周期(請記住,在任何給定時間只有2.5MB的生存對象),我們便停止將對象提升到舊空間。
繼續監視JVM,我們發現采用后舊空間使用率是恒定的。 沒有更多的對象傳播到舊的對象,但是由于沒有觸發任何主要的GC,在適應發生之前設法傳播的約10MB垃圾將永遠存在于舊的空間中。
如果您確定自己在做什么,還可以選擇“驚人的適應性”。 在JVM參數中指定-XX-UseAdaptiveSizingPolicy將指示JVM堅持在啟動時給定的參數,而不是試圖超越您。 謹慎使用此選項,現代JVM通常非常擅長為您預測合適的配置。
翻譯自: https://www.javacodegeeks.com/2014/10/adaptive-heap-sizing.html
總結
- 上一篇: 怎样重装win7系统电脑如何格式化重装系
- 下一篇: 不变性如何提供帮助