我們在tomcat 7,JDK 7,Amazon Linux中有一個Web應用程序。這是我們對GC配置的要求:Java CMS GC,系統空閒時佔用CPU的GC線程
-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled"
我們沒有啓用「PrintGCDetails」。
這就是每隔幾秒打印出來的gc.log文件(爲48小時,此時的應用程序在0負載下 - 絕對沒有活動,甚至下面的內容被打印出來並且CPU採取這些線程是15%)(請參閱下面的上下文中):
940568.925: [GC 7425641K(8277888K), 0.2201750 secs]
940572.415: [GC 7425641K(8277888K), 0.1782950 secs]
940574.101: [GC 7425641K(8277888K), 0.1736550 secs]
940577.545: [GC 7425647K(8277888K), 0.1779190 secs]
而且我們看到,下面的GC線程佔用CPU(約15%的總),即使:
- 系統中沒有任何活動,
- 沒有其他線程處於活動狀態,除此之外,此狀態持續48小時,系統此時處於0負載下。
- 系統是0負載下也爲前24小時,然後這些線程變得活躍
- 當這些線程是活躍的並且佔用CPU,前述系在gc.log
- 此繼續印刷2天,當我們最終通過在此JVM中調用Web應用程序5分鐘來加載時,然後它全部停止。我們注意到這些線程現在不再需要CPU(他們正在使用< 1%)。這個問題在完成GC發生後似乎已經解決了。完整的GC發生在系統負載後。
- 簡而言之,當系統處於0負載下48小時時,GC線程繼續佔用15%CPU。
這些線程:
"Gang worker#0 (Parallel GC Threads)" prio=10 tid=0x00007fad9402e000 nid=0x629d runnable
"Gang worker#1 (Parallel GC Threads)" prio=10 tid=0x00007fad94030000 nid=0x629e runnable
"Gang worker#2 (Parallel GC Threads)" prio=10 tid=0x00007fad94031800 nid=0x629f runnable
"Gang worker#3 (Parallel GC Threads)" prio=10 tid=0x00007fad94033800 nid=0x62a0 runnable
"Gang worker#4 (Parallel GC Threads)" prio=10 tid=0x00007fad94035800 nid=0x62a1 runnable
"Gang worker#5 (Parallel GC Threads)" prio=10 tid=0x00007fad94037000 nid=0x62a2 runnable
"Gang worker#6 (Parallel GC Threads)" prio=10 tid=0x00007fad94039000 nid=0x62a3 runnable
"Gang worker#7 (Parallel GC Threads)" prio=10 tid=0x00007fad9403b000 nid=0x62a4 runnable
"Gang worker#8 (Parallel GC Threads)" prio=10 tid=0x00007fad9403d000 nid=0x62a5 runnable
"Gang worker#9 (Parallel GC Threads)" prio=10 tid=0x00007fad9403e800 nid=0x62a6 runnable
"Gang worker#10 (Parallel GC Threads)" prio=10 tid=0x00007fad94040800 nid=0x62a7 runnable
"Gang worker#11 (Parallel GC Threads)" prio=10 tid=0x00007fad94042800 nid=0x62a8 runnable
"Gang worker#12 (Parallel GC Threads)" prio=10 tid=0x00007fad94044000 nid=0x62a9 runnable
"Concurrent Mark-Sweep GC Thread" prio=10 tid=0x00007fad9418b000 nid=0x62ae runnable
"Gang worker#0 (Parallel CMS Threads)" prio=10 tid=0x00007fad94183000 nid=0x62aa runnable
"Gang worker#1 (Parallel CMS Threads)" prio=10 tid=0x00007fad94185000 nid=0x62ab runnable
"Gang worker#2 (Parallel CMS Threads)" prio=10 tid=0x00007fad94187000 nid=0x62ac runnable
"Gang worker#3 (Parallel CMS Threads)" prio=10 tid=0x00007fad94188800 nid=0x62ad runnable
問題1:爲什麼會GC日誌中充滿時,這些線程正在以下15%的CPU?
940568.925: [GC 7425641K(8277888K), 0.2201750 secs]
940572.415: [GC 7425641K(8277888K), 0.1782950 secs]
問題2:上述日誌是否表明CMS(標記,掃描等)失敗?
問題3:爲什麼當我們在Web應用程序中引入中等負載併發生FULL GC時,它會自行解決?
是的,我會嘗試在啓用printGCDetails的另一個環境中複製問題並返回信息或解決方案 - 如果有人以前看到過這個問題,請添加到對話中。
編輯1:這是日誌時 「PrintGCDetails」 已啓用:
1376.326: [GC [1 CMS-initial-mark: 6481517K(7281088K)] 6536750K(8277888K), 0.0094620 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
1376.336: [CMS-concurrent-mark-start]
1377.992: [CMS-concurrent-mark: 1.656/1.656 secs] [Times: user=6.62 sys=0.00, real=1.66 secs]
1377.992: [CMS-concurrent-preclean-start]
1378.005: [CMS-concurrent-preclean: 0.014/0.014 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
1378.006: [CMS-concurrent-abortable-preclean-start]
CMS: abort preclean due to time 1413.110: [CMS-concurrent-abortable-preclean: 4.169/35.104 secs] [Times: user=4.23 sys=0.01, real=35.11 secs]
1413.111: [GC[YG occupancy: 55233 K (996800 K)]1413.111: [Rescan (parallel) , 0.0154040 secs]1413.126: [weak refs processing, 0.0001380 secs]1413.126: [class unloading, 0.0013450 secs]1413.128: [scrub symbol table, 0.0023140 secs]1413.130: [scrub string table, 0.0004850 secs] [1 CMS-remark: 6481517K(7281088K)] 6536751K(8277888K), 0.0201870 secs] [Times: user=0.20 sys=0.00, real=0.02 secs]
1413.131: [CMS-concurrent-sweep-start]
1414.151: [CMS-concurrent-sweep: 1.020/1.020 secs] [Times: user=1.02 sys=0.00, real=1.02 secs]
1414.151: [CMS-concurrent-reset-start]
1414.177: [CMS-concurrent-reset: 0.026/0.026 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]
還要注意:在 「CMSMaxAbortablePrecleanTime」 設置爲35秒。 謝謝。
通過佔用堆的大小,您意味着應用程序加載/啓動後或完全GC發生後的大小?謝謝 – Casey
假設已經爲工作流程加載了應用程序並且發生了完整的gc。最初將堆的大小增加到一個較大的值,然後運行工作流並查看堆的增長情況。然後調用完整的gc並查看值。那將是被佔領的堆。嘗試並將堆設置爲佔用堆爲70%左右的值。重複,看看這個問題是否消失。 – Khanna111