【生產環境】Tomcat運行一段時間後訪問變慢分析歷程

環境運行一天或者幾天,網站訪問就很卡,手機端app訪問頁面出現白屏。Tomcat運行一段時間後訪問變慢,可是cpu,內存都正常。日誌也是發現不了啥....java

問題的原先分析

1.環境配置(cpu,內存,使用工具:nmon工具、visualvm工具、jprofiler工具所有用上監控中)linux

2.修改info日誌,啓用error級別日誌(待篩選排查)web

3.查看數據庫配置鏈接池(正常)數據庫

4.代碼問題對象建立太多(待排查,web裏面走攔截器待看)tomcat

5.jvm分配內存太少了(調優,生產環境重啓)網絡

6.併發高了,網站太多人訪問(排除)多線程

7.webapps下面的工程太多了(排除)併發

8.數據壓力太大數據盤大(排除)app

9.物理機器問題、網絡寬度問題...less

Linux環境配置信息

Tomcat啓動行參數的優化

修改前:

JAVA_OPTS="-Xmx2048m -Xms1024m -Xmn384M -XX:MaxPermSize=512m -XX:PermSize=128m"
進行重修調整,修改後:

JAVA_OPTS="-server -Xmx2048m -Xms2048m -Xmn384M -XX:PermSize=512m -XX:MaxPermSize=512m -Xss512k -XX:+AggressiveOpts -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:-UseGCOverheadLimit -XX:+HeapDumpOnOutOfMemoryError -XX:CMSInitiatingOccupancyFraction=75 -XX:CMSFullGCsBeforeCompaction=2 -XX:SoftRefLRUPolicyMSPerMB=0 -Djava.awt.headless=true "
參數解釋:

-server :

tomcat是運行在生產環境中的,這個參數必須上,由於tomcat默認是以一種叫java –client的模式來運行的,server即意味着你的tomcat是以真實的production的模式在運行的,這也就意味着tomcat以server模式運行時將擁有:更大、更高的併發處理能力,更快更強捷的JVM垃圾回收機制,能夠得到更多的負載與吞吐量更等

-Xmx2048m -Xms2048m

即JVM內存設置了,把Xms與Xmx兩個值設成同樣是最優的作法。存放 new MyClass() 的對象,是GC的主要區域,-Xms / -Xmx 分別是堆的初始容量、最大可擴展容量,建議初始值設置爲最大值,以避免反覆擴展或縮減的開銷;

-Xmx2048m:設置JVM最大可用內存爲2048M。
-Xms2048m:設置JVM促使內存爲3550m。此值能夠設置與-Xmx相同,以免每次垃圾回收完成後JVM從新分配內存。

-Xmn512m

設置年輕代大小爲512m。整個堆大小=年輕代大小 + 年老代大小 + 持久代大小。持久代通常固定大小爲64m,因此增大年輕代後,將會減少年老代大小。此值對系統性能影響較大,Sun官方推薦配置爲整個堆的3/8。

-XX:PermSize=512m -XX:MaxPermSize=512m

JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;在數據量的很大的文件導出時,必定要把這兩個值設置上,不然會出現內存溢出的錯誤。由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。那麼,若是是物理內存4GB,那麼64分之一就是64MB,這就是PermSize默認值,也就是永生代內存初始大小;四分之一是1024MB,這就是MaxPermSize默認大小。

-Xss512k

是指設定每一個線程的堆棧大小。這個就要依據你的程序,看一個線程 大約須要佔用多少內存,可能會有多少線程同時運行等。通常不易設置超過1M,要否則容易出現out ofmemory。

設置每一個線程的堆棧大小。JDK5.0之後每一個線程堆棧大小爲1M,之前每一個線程堆棧大小爲256K。更具應用的線程所需內存大小進行調整。在相同物理內存下,減少這個值能生成更多的線程。可是操做系統對一個進程內的線程數仍是有限制的,不能無限生成,經驗值在3000~5000左右。

-XX:+AggressiveOpts

做用如其名(aggressive),啓用這個參數,則每當JDK版本升級時,你的JVM都會使用最新加入的優化技術(若是有的話)

-XX:+DisableExplicitGC

在程序代碼中不容許有顯示的調用」System.gc()」。看到過有兩個極品工程中每次在DAO操做結束時手動調用System.gc()一下,以爲這樣作好像可以解決它們的out ofmemory問題同樣,付出的代價就是系統響應時間嚴重下降,就和我在關於Xms,Xmx裏的解釋的原理同樣,這樣去調用GC致使系統的JVM大起大落,

-XX:+UseBiasedLocking

啓用一個優化了的線程鎖,咱們知道在咱們的appserver,每一個http請求就是一個線程,有的請求短有的請求長,就會有請求排隊的現象,甚至還會出現線程阻塞,這個優化了的線程鎖使得你的appserver內對線程處理自動進行最優調配。

-XX:MaxTenuringThreshold=31

設置垃圾最大年齡。若是設置爲0的話,則年輕代對象不通過Survivor區,直接進入年老代。對於年老代比較多的應用,能夠提升效率。若是將此值設置爲一個較大值,則年輕代對象會在Survivor區進行屢次複製,這樣能夠增長對象再年輕代的存活時間,增長在年輕代即被回收的機率。這個值的設置是根據本地的jprofiler監控後獲得的一個理想的值,不能一律而論原搬照抄。

-XX:+UseConcMarkSweepGC

即CMS gc,這一特性只有jdk1.5即後續版本才具備的功能,它使用的是gc估算觸發和heap佔用觸發。咱們知道頻頻繁的GC會造面JVM的大起大落從而影響到系統的效率,所以使用了CMS GC後能夠在GC次數增多的狀況下,每次GC的響應時間卻很短,好比說使用了CMS GC後通過jprofiler的觀察,GC被觸發次數很是多,而每次GC耗時僅爲幾毫秒。

-XX:+UseParNewGC 

對年輕代採用多線程並行回收,這樣收得快。

-XX:+CMSParallelRemarkEnabled

在使用UseParNewGC 的狀況下, 儘可能減小 mark 的時間

-XX:+UseCMSCompactAtFullCollection

在使用concurrent gc 的狀況下, 防止 memoryfragmention, 對live object 進行整理, 使 memory 碎片減小。

-XX:LargePageSizeInBytes=128m  

指定 Java heap的分頁頁面大小

-XX:+UseFastAccessorMethods

get,set 方法轉成本地代碼

-XX:+UseCMSInitiatingOccupancyOnly

指示只有在 oldgeneration 在使用了初始化的比例後concurrent collector 啓動收集

-XX:CMSInitiatingOccupancyFraction=70

CMSInitiatingOccupancyFraction,這個參數設置有很大技巧,基本上知足(Xmx-Xmn)(100- CMSInitiatingOccupancyFraction)/100>=Xmn就不會出現promotion failed。在個人應用中Xmx是6000,Xmn是512,那麼Xmx-Xmn是5488兆,也就是年老代有5488 兆,CMSInitiatingOccupancyFraction=90說明年老代到90%滿的時候開始執行對年老代的併發垃圾回收(CMS),這時還 剩10%的空間是548810%=548兆,因此即便Xmn(也就是年輕代共512兆)裏全部對象都搬到年老代裏,548兆的空間也足夠了,因此只要滿 足上面的公式,就不會出現垃圾回收時的promotion failed;

所以這個參數的設置必須與Xmn關聯在一塊兒。

-XX:-UseGCOverheadLimit

-XX:+HeapDumpOnOutOfMemoryError

-XX:CMSInitiatingOccupancyFraction=75

-XX:CMSFullGCsBeforeCompaction=2

-XX:SoftRefLRUPolicyMSPerMB=0

-Djava.awt.headless=true

這個參數通常咱們都是放在最後使用的,這全參數的做用是這樣的,有時咱們會在咱們的J2EE工程中使用一些圖表工具如:jfreechart,用於在web網頁輸出GIF/JPG等流,在winodws環境下,通常咱們的app server在輸出圖形時不會碰到什麼問題,可是在linux/unix環境下常常會碰到一個exception致使你在winodws開發環境下圖片顯示的好好但是在linux/unix下卻顯示不出來,所以加上這個參數以避免避這樣的狀況出現。

-XX:+UseParallelOldGC

-XX:+PrintGCDateStamps

-XX:+PrintGCDetails

-Xloggc:/opt/lucky/app/lucky/tomcat/logs/gc.log

上述這樣的配置,基本上能夠達到:系統響應時間增快、JVM回收速度增快同時又不影響系統的響應率、JVM內存最大化利用、線程阻塞狀況最小化。

Tomcat啓動慢調整
JVM環境中解決:

打開vi $JAVA_HOME/jre/lib/security/java.security這個文件,找到下面的內容:

securerandom.source=file:/dev/urandom

替換成

securerandom.source=file:/dev/./urandom

 

代碼模塊進行

數據庫查詢語句進行

 

參考:

JVM調優總結 -Xms -Xmx -Xmn -Xss

http://unixboy.iteye.com/blog/174173

相關文章
相關標籤/搜索