文章來源
https://hllvm-group.iteye.com/group/topic/39440
一、問題描述
Attaching to process ID 26424, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.231-b11
using thread-local object allocation.
Parallel GC with 15 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 1073741824 (1024.0MB)
NewSize = 357564416 (341.0MB)
MaxNewSize = 357564416 (341.0MB)
OldSize = 716177408 (683.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 268435456 (256.0MB)
used = 268435456 (256.0MB)
free = 0 (0.0MB)
100.0% used
From Space:
capacity = 44564480 (42.5MB)
used = 425984 (0.40625MB)
free = 44138496 (42.09375MB)
0.9558823529411765% used
To Space:
capacity = 44564480 (42.5MB)
used = 0 (0.0MB)
free = 44564480 (42.5MB)
0.0% used
PS Old Generation
capacity = 716177408 (683.0MB)
used = 577780552 (551.0144729614258MB)
free = 138396856 (131.98552703857422MB)
80.67561829596278% used
41099 interned Strings occupying 4972688 bytes.
啓動參數是:
-Xms2048m -Xmx2048m -XX:NewSize=256m -XX:PermSize=256m -server -XX:+DisableExplicitGC -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails
SurvivorRatio是 8 ,這個時候Eden 也 600多M,爲啥From/To 幾乎是 0 呢?
Jdk version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)
二、解決方法
因爲ParallelScavenge GC會動態調整各個區的大小。這個行爲叫做adaptive size policy。要禁用的話請用 -XX:-UseAdaptiveSizePolicy 。可以通過 -XX:+PrintAdaptiveSizePolicy 來觀察它對各個區的大小的調整。
如果survivor space都幾乎變成0了,多半意味着tenuring threshold已經降到1了,也就是說所有eden裏活的對象在經歷第一次minor GC的時候就會被晉升到old generation。那樣的話survivor space就完全沒用了,所以會被設置到幾乎0。(無法真的完全設置到0大小是實現上的細節…有分區之間有對齊需求)
爲啥tenuring threshold會下降,最終降到1?有兩種可能:
- minor GC耗時比期望的時間長。爲了降低minor GC的耗時,降低tenuring threshold來讓更多對象晉升,減少留在young generation裏的對象
- survivor space有溢出
說到底還是創建對象太多太快了