1. 程式人生 > >tomcat效能優化

tomcat效能優化

Tomcat 的啟動引數位於tomcat的安裝目錄\bin目錄下,如果你是Linux作業系統就是catalina.sh檔案,如果你是Windows作業系統那麼你需要改動的就是catalina.bat檔案。開啟該檔案,一般該檔案頭部是一堆的由##包裹著的註釋文字,找到註釋文字的最後一段如:

# $Id: catalina.sh 522797 2007-03-27 07:10:29Z fhanik $

# -----------------------------------------------------------------------------

# OS specific support.  $var _must_ be set to either true or false.

敲入一個回車,加入如下的引數

Linux系統中tomcat的啟動引數

export JAVA_OPTS="-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC  -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m  -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true "

Windows系統中tomcat的啟動引數

set JAVA_OPTS=-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC  -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m  -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true

上面引數好多啊,可能有人寫到現在都沒見一個tomcat的啟動命令里加了這麼多引數,當然,這些引數只是我機器上的,不一定適合你,尤其是引數後的value(值)是需要根據你自己的實際情況來設定的。

引數解釋:

ü   -server

我不管你什麼理由,只要你的tomcat是執行在生產環境中的,這個引數必須給我加上

因為tomcat預設是以一種叫java –client的模式來執行的,server即意味著你的tomcat是以真實的production的模式在執行的,這也就意味著你的tomcat以server模式執行時將擁有:更大、更高的併發處理能力,更快更強捷的JVM垃圾回收機制,可以獲得更多的負載與吞吐量。。。更。。。還有更。。。

Y給我記住啊,要不然這個-server都不加,那是要打屁股了。

ü   -Xms–Xmx

即JVM記憶體設定了,把Xms與Xmx兩個值設成一樣是最優的做法,有人說Xms為最小值,Xmx為最大值不是挺好的,這樣設定還比較人性化,科學化。人性?科學?你個頭啊。

大家想一下這樣的場景:

一個系統隨著併發數越來越高,它的記憶體使用情況逐步上升,上升到最高點不能上升了,開始回落,你們不要認為這個回落就是好事情,由其是大起大落,在記憶體回落時它付出的代價是CPU高速開始運轉進行垃圾回收,此時嚴重的甚至會造成你的系統出現“卡殼”就是你在好好的操作,突然網頁像死在那邊一樣幾秒甚至十幾秒時間,因為JVM正在進行垃圾回收。

因此一開始我們就把這兩個設成一樣,使得Tomcat在啟動時就為最大化引數充分利用系統的效率,這個道理和jdbcconnection pool裡的minpool size與maxpool size的需要設成一個數量是一樣的原理。

如何知道我的JVM能夠使用最大值啊?拍腦袋?不行!

在設這個最大記憶體即Xmx值時請先開啟一個命令列,鍵入如下的命令:

看,能夠正常顯示JDK的版本資訊,說明,這個值你能夠用。不是說32位系統下最高能夠使用2GB記憶體嗎?即:2048m,我們不防來試試

可以嗎?不可以!不要說2048m呢,我們小一點,試試1700m如何

嘿嘿,連1700m都不可以,更不要說2048m了呢,2048m只是一個理論數值,這樣說吧我這邊有幾臺機器,有的機器-Xmx1800都沒問題,有的機器最高只能到-Xmx1500m。

因此在設這個-Xms與-Xmx值時一定一定記得先這樣測試一下,要不然直接加在tomcat啟動命令列中你的tomcat就再也起不來了,要飛是飛不了,直接成了一隻瘟貓了。

ü   –Xmn

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

ü   -Xss

是指設定每個執行緒的堆疊大小。這個就要依據你的程式,看一個執行緒 大約需要佔用多少記憶體,可能會有多少執行緒同時執行等。一般不易設定超過1M,要不然容易出現out ofmemory。

ü   -XX:+AggressiveOpts

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

ü   -XX:+UseBiasedLocking

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

ü   -XX:PermSize=128M-XX:MaxPermSize=256M

JVM使用-XX:PermSize設定非堆記憶體初始值,預設是實體記憶體的1/64;

在資料量的很大的檔案匯出時,一定要把這兩個值設定上,否則會出現記憶體溢位的錯誤。

由XX:MaxPermSize設定最大非堆記憶體的大小,預設是實體記憶體的1/4。

那麼,如果是實體記憶體4GB,那麼64分之一就是64MB,這就是PermSize預設值,也就是永生代記憶體初始大小;

四分之一是1024MB,這就是MaxPermSize預設大小。

ü   -XX:+DisableExplicitGC

在程式程式碼中不允許有顯示的呼叫”System.gc()”。看到過有兩個極品工程中每次在DAO操作結束時手動呼叫System.gc()一下,覺得這樣做好像能夠解決它們的out ofmemory問題一樣,付出的代價就是系統響應時間嚴重降低,就和我在關於Xms,Xmx裡的解釋的原理一樣,這樣去呼叫GC導致系統的JVM大起大落,效能不到什麼地方去喲!

ü   -XX:+UseParNewGC

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

ü   -XX:+UseConcMarkSweepGC

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

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

ü   -XX:MaxTenuringThreshold

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

這個值的設定是根據本地的jprofiler監控後得到的一個理想的值,不能一概而論原搬照抄。

ü   -XX:+CMSParallelRemarkEnabled

在使用UseParNewGC 的情況下, 儘量減少 mark 的時間

ü   -XX:+UseCMSCompactAtFullCollection

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

ü   -XX:LargePageSizeInBytes

指定 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%的空間是5488*10%=548兆,所以即使Xmn(也就是年輕代共512兆)裡所有物件都搬到年老代裡,548兆的空間也足夠了,所以只要滿 足上面的公式,就不會出現垃圾回收時的promotion failed;

因此這個引數的設定必須與Xmn關聯在一起。

ü   -Djava.awt.headless=true

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

上述這樣的配置,基本上可以達到:

ü   系統響應時間增快

ü   JVM回收速度增快同時又不影響系統的響應率

ü   JVM記憶體最大化利用

ü   執行緒阻塞情況最小化

Tomcat容器內的優化