2012-11-24 67 views
5

Som背景信息;Linux使用運行Java的系統/內核CPU GC

服務器;

帶有130 GB Ram的新SLES 12服務器旨在爲大型數據庫(150G +數據)運行MySQL。

服務器還將託管一些Java應用程序。

Java版本(默認從Oracle) - Java(註冊商標)SE運行時環境(建立1.7.0-B147) - 爪哇熱點(TM)64位服務器VM(構建21.0-B17,混合模式)

我們偶然發現了以下問題;

運行一些特殊的Java應用程序使kerne /系統cpu峯值減速/暫停應用程序的時間週期。我通過製作一個簡單地隨時間消耗內存並使用一些cpu的Java應用程序來轉載它。

調查顯示減速過程中的聯繫數量很高(10000-25000)。

每次減速後,Java已經獲得了更多的內存。將Java設置爲以固定內存啓動似乎也可以減少問題(將-Xmx和-Xms設置爲相同的值)。 Verbosing垃圾收集也表明GC正在踢腳,可能是觸發器。

GC和內存分配由於某種原因是非常昂貴的,我們不確定從哪裏看這裏。從GC詳細:

[GC^C 1024064K->259230K(3925376K), 87,3591890 secs] 

在低端Linux服務器相同的程序(從SUN運行SLES,爪哇1.6.0_11)運行GC;減速期間

[GC 1092288K->253266K(3959488K), 3.0125460 secs]  

TOP:減速(從3行)期間

top - 11:23:33 up 87 days, 19:55, 5 users, load average: 14.27, 4.50, 10.17 
Tasks: 250 total, 39 running, 211 sleeping, 0 stopped, 0 zombie 
Cpu(s): 0.0%us, 71.8%sy, 0.0%ni, 28.2%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st 
Mem: 129033M total, 128576M used,  457M free,  1388M buffers 
Swap: 32765M total,  13M used, 32752M free, 113732M cached 

的vmstat;

procs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------ 
r b swpd free buff cache si so bi bo in cs us sy id wa st 
0 0 13552 1714328 1422268 116462260 0 0 10  9 0 0 0 0 100 0 0 
1 0 13552 1241780 1422268 116462292 0 0  0  0 240 353 1 0 99 0 0 
1 0 13552 695616 1422268 116462292 0 0  0 17 419 431 3 0 97 0 0 
55 0 13552 486384 1422268 116462292 0 0  0  2 20228 458 1 57 43 0 0 
75 0 13552 476172 1422268 116462300 0 0  0  8 12782 684 0 70 30 0 0 
65 0 13552 470304 1422268 116462304 0 0  0  0 13108 792 0 72 28 0 0 

爲什麼GC在高端服務器和低端服務器上如此昂貴?任何想法在哪裏尋找線索?

更新 - 調用參數2012-11-26 調用參數;

java -Xmx4g -Xms4g -verbose:gc -server -cp "./dest/" UseMemoryMain 

給予

[GC^C 1024064K->259230K(3925376K), 87,3591890 secs] 

改爲;

java -Xmx4g -Xms4g -XX:+UseParallelGC -verbose:gc -cp "./dest/" UseMemoryMain 

給予

[GC 1048640K->265430K(4019584K), 0,0902660 secs] 

改爲;

java -Xmx4g -Xms4g -XX:+UseConcMarkSweepGC -verbose:gc -cp "./dest/" UseMemoryMain 

給予

[GC 1092288K->272230K(3959488K), 0,1791320 secs] 

什麼是真正有趣的是,今天重新運行瞞着其中GC方法使用給出了這樣的;

java -Xmx4g -Xms4g -verbose:gc -server -cp "./dest/" UseMemoryMain 

給予

[GC 1024064K->259238K(3925376K), 0,0839190 secs] 

Java已經改變了策略,以某種方式違約GC ...

+2

簡單地強制應用程序使用並行1 GC做出了區別; -XX:+ UseParallelGC [GC 1048640K-> 265430K(4019584K),0,0902660秒] – ZiggyF2B

回答

4

垃圾收集確實是一個棘手的話題。 爲了給出最佳答案,您應該發佈用於調用java的完整命令行。

正如你所說的與GC開關擱淺有所幫助。原因在於,對於現在使用的許多應用程序來說,缺省設置不是最佳的。對於許多許多應用,這些都要求有快速的反應,因爲它們是互動的,參數

-XX:+ UseConcMarkSweepGC

會造成很大的差別。

值得注意的是,使用你提到的JVM,使用更大的堆(可以說更大的10GB)總是需要一些調整。記下你擁有的GC日誌,並觀察你使用GC選項時的行爲改變。我會推薦嘗試不同的收集器策略(如CMS或G1),並使用Eden Space的配置(如Xmn)。

最後但並非最不重要的是,您可以使用Profiler調查應用程序如何處理內存。也許代碼可以改進,因此可以避免大量的GC。

+0

謝謝,我已經更新了發射參數。當我今天重新運行示例應用程序而沒有GC參數時,JVM已經改變了策略,默認情況下GC是「快速」的。 – ZiggyF2B

相關問題