使用tomcat java進程佔用cpu偏高的原因

來源:互聯網
上載者:User

使用tomcat做為java容器,cpu佔用偏高的原因,目前公司伺服器上面跑的ubuntu環境nginx+tomcat+mysql運行一段時間之後java進程cpu偏高,會出現網站打不開的情況。所以進行了如下分析。


一,首先查看tomcat日誌,如果有出現OOM錯誤(記憶體溢出)可以對應的加大jvm的記憶體大小。

1,修改tomcat目錄下bin目錄下的catalina.sh檔案,在

#JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask`"

這行下面添加如下內容


JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xmn512m -XX:PermSize=256M -XX:MaxPermSize=256m -Xss256k -XX:SurvivorRatio=4 -XX:MaxTenuringThreshold=20 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=73 -XX:+UseCMSCompactAtFullCollection -XX:+CMSParallelRemarkEnabled -XX:CMSFullGCsBeforeCompaction=2 -Djava.awt.headless=true"


上面的配置是基於4G記憶體設定的,具體修改看自己手上伺服器的配置。

參數的含義:

-server 告訴tomcat使用server模式 能獲得更大並發數和效能

-Xms2048m -Xmx2048m JVM記憶體的總數

-Xmn512m 年輕代記憶體大小

-XX:PermSize=256M -XX:MaxPermSize=256m 永久帶記憶體大小

Xss256k 線程大小

-XX:SurvivorRatio=4 設定年輕代中Eden區與Survivor區的大小比值。設定為4,則兩個Survivor區與一個Eden區的比值為2:4,一個Survivor區占整個年輕代的1/6

-XX:MaxTenuringThreshold=20 設定垃圾最大年齡。如果設定為0的話,則年輕代對象不經過Survivor區,直接進入年老代。對於年老代比較多的應用,可以提高效率。如果將此值設定為一個較大值,則年輕代對象會在Survivor區進行多次複製,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的機率

-XX:+UseParNewGC 對年輕代採用多線程並行回收,這樣收得快

XX:+UseConcMarkSweepGC

CMS gc,這一特性只有jdk1.5即後續版本才具有的功能,它使用的是gc估算觸發和heap佔用觸發。

我們知道頻頻繁的GC會造面JVM的大起大落從而影響到系統的效率,因此使用了CMS GC後可以在GC次數增多的情況下,每次GC的回應時間卻很短,比如說使用了CMS GC後經過jprofiler的觀察,GC被觸發次數非常多,而每次GC耗時僅為幾毫秒

-XX:CMSInitiatingOccupancyFraction=73 說明年老代到73%滿的時候開始執行對年老代的並發記憶體回收(CMS)。

-XX:+UseCMSCompactAtFullCollection 開啟對年老代的壓縮。可能會影響效能,但是可以消除片段

-XX:+CMSParallelRemarkEnabled 降低標記停頓

-XX:CMSFullGCsBeforeCompaction 由於並發收集器不對記憶體空間進行壓縮、整理,所以運行一段時間以後會產生“片段”,使得運行效率降低。此值設定運行多少次GC以後對記憶體空間進行壓縮、整理。


參考網站:http://blog.csdn.net/lifetragedy/article/details/7708724


2,修改參數之後重啟tomcat,查看參數是否生效

jmap -heap javaPID 查看JVM記憶體配置情況

jstat -gcutil javaPID 1000 30 查看JVM記憶體回收情況


經過上面的修改應該就可以完成對tomcat進程飆高的情況了。如果運行一段時間之後通過jstat查看各個記憶體代的使用方式,發現老年代100% 一直在觸發FULL GC 那就是記憶體大小的原因了。有條件的可以添加記憶體,沒條件的可以設定 每天重啟一次tomcat或者一個星期重啟一次來釋放jvm記憶體。問題解決。


二,如果想查看是否是代碼層的原因,就需要另外的辦法

1,使用命令jstack命令查看佔用CPU最高的線程。

PID=`ps aux | grep java | head -1 | awk '{print $2}'`

ps -mp $PID -o THREAD,tid,time | sort -k 2 -r | head -20


echo -n -e " shur ru:"

read f


if [ -z $f ]

then

echo "no"

else

jstack "$PID" | grep `printf "%x\n" $f` -A 30

fi

一個簡單的監控指令碼,查看JAVA進程佔用CPU最高的線程在做什麼以此來分析是否是代碼層的問題。

參考網站:http://blog.csdn.net/blade2001/article/details/9065985

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.