這個錯誤是cms專有錯誤,並發清楚線程和工作線程同時工作,清理出來年老代的空間不足以存放由新生代晉升導年老代的對象
從而導致年老代垃圾回收變成了Serial Old,從而暫停應用程序,停頓時間過長
現象:
(concurrent mode failure): 1048576K->185976K(1048576K), 1.4906868 secs] 1520447K->185976K(1520448K), [Metaspace: 140571K->140571K(1183744K)], 1.4909291 secs] [Times: user=1.96 sys=0.00, real=1.49 secs]
Heap after GC invocations=27553 (full 48):
par new generation total 471872K, used 0K [0x00000000a0000000, 0x00000000c0000000, 0x00000000c0000000)
eden space 429456K, 0% used [0x00000000a0000000, 0x00000000a0000000, 0x00000000b99a0000)
from space 51413K, 0% used [0x00000000bccd0000, 0x00000000bccd0000, 0x00000000c0000000)
to space 52416K, 0% used [0x00000000b99a0000, 0x00000000b99a0000, 0x00000000bccd0000)
concurrent mark-sweep generation total 1048476K, used 183976K [0x00000000c0000000, 0x0000000100000000, 0x0000000100000000)
Metaspace used 140571K, capacity 152156K, committed 152836K, reserved 1183744K
class space used 15971K, capacity 18769K, committed 18896K, reserved 1048576K
}
可能原因:1 年輕代產生大對象直接放入年老代,- XX:PretenureSizeThreshold = <字節大小>(默認為0,即不直接在年老代創對象,且該參數只對serial 和parallel new收集器有效)所以一般要檢查代碼,避免創建大量的大對象
2 cms觸發太晚(一般默認值,不會這個原因造成) -XX:CMSInitiatingOccupancyFraction=N調小
3 內存碎片太多,
-XX:+UseCMSCompactAtFullCollection (空間碎片整理)
-XX:CMSFullGCsBeforeCompaction=n
4 檢查年輕代年老代比例是否合適
晉升閾值過小,可以根據對象大小或年紀來調(一般默認即可);
Survivor,Eden年輕代過小,導致晉升速率提高