最近開始優(yōu)化頁游服務(wù)端的性能,一些心得總結(jié)一下?,F(xiàn)在的服務(wù)器硬件越來越好,幾十G內(nèi)存,十幾個CPU。當(dāng)硬件不是瓶頸的時候,如果讓程序發(fā)揮最大效用就成了我們需要考慮的問題。就游戲服務(wù)器來說,得滿足幾個要求,高負(fù)載,低延時。特別是在開服當(dāng)天,大量用戶會涌進來,可能給服務(wù)器造成壓力。使用Java作為服務(wù)器語言,除了程序本身的性能外,JVM的配置也直接影響到系統(tǒng)性能。 參數(shù)調(diào)優(yōu) 1 入門級別的配置一般是:java -server -Xmx5000m Xms5000m 服務(wù)器端的jvm運行程序記得都最好加上 -server 很多默認(rèn)參數(shù)都會根據(jù)這個運行模式來優(yōu)化。這里設(shè)置了最大內(nèi)存和最小內(nèi)存,一般都是配置成相同的,可以減少內(nèi)存申請和伸縮帶來的性能損耗 2 加入垃圾回收算法的配置:java -server -Xmx5000m -Xms5000m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC 關(guān)于垃圾回收的具體算法介紹我這里就不詳細描述了,可以參考我以前的文章 我們都有一個常識,就是盡量減少JVM的full gc的次數(shù)和時間,因為full gc 會導(dǎo)致整個系統(tǒng)的暫停(stop the world).為此,我們?yōu)槔夏甏x擇了UseConcMarkSweepGC 選擇了并發(fā)gc算法,也為新生代選擇了多線程的并行gc算法UseParNewGC。 3 設(shè)置新生代的內(nèi)存大小 java -server -Xmx5000m -Xms5000m -Xmn800m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC Xmn是新生代的內(nèi)存大小,包括(eden+ 2 survivor space)。這個參數(shù)設(shè)置直接影響系統(tǒng)的響應(yīng)速度。在java程序中new一個對象,首先是放在eden區(qū)域,eden滿了后,觸發(fā)gc,存活下來的對象被拷貝到survivor區(qū)。經(jīng)過若干次yong gc后,如果依然存活下來,就會進入老年代。新生代設(shè)置大了,會導(dǎo)致一次yong gc的時間消耗大,設(shè)置小了,又會很快滿了,導(dǎo)致yong gc的頻率過高。新生代不宜設(shè)置過大,因為新生代大了,老年代的內(nèi)存就小了,老年代內(nèi)存小,會導(dǎo)致full gc發(fā)生的頻率變大。Xmn也沒有一個確切的算法,根據(jù)你自身的業(yè)務(wù)系統(tǒng)決定的。我在設(shè)置的游戲服務(wù)器的時候,一般采用模擬大量并發(fā)用戶的行為,調(diào)整Xmn的大小,同時監(jiān)控gc的時間和頻率,選擇一個合適的大小。下面我會提到怎么用工具來監(jiān)控gc。 4 設(shè)置一些額外的高級參數(shù) java -server -Xmx5000m -Xms5000m -Xmn800m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 使用CMS進行老年代gc,會容易導(dǎo)致一些內(nèi)存碎片,導(dǎo)致內(nèi)存利用率降低,為此,加入 UseCMSCompactAtFullCollection 可以保證在full gc時進行內(nèi)存壓縮,減少內(nèi)存碎片。CMSInitiatingOccupancyFraction=70 表示老年代內(nèi)存達到70%時觸發(fā)。這個參數(shù)要特別小心,設(shè)置得過小會導(dǎo)致full gc沒有完成,yong gc的對象遷移過來,導(dǎo)致整個老年代內(nèi)存都滿了 工具 § jstat 用來實時查看gc的狀態(tài), 用法:jstat -gcutil 進程號 時間(毫秒)。結(jié)果如下: 里面列出每個區(qū)間的內(nèi)存大小,新生代gc的次數(shù)和時間,老年代gc的次數(shù)和時間。這里都能反映出你的JVM的運行狀況 § jmap 用于查看java進程的對象狀況 用法:jmap -histo:live 進程id ??梢源蛴∶總€類的實例數(shù)量,內(nèi)存大小 用法:jmap -dump:format=b,file=log.bin 進程id 這個命令特別有用,可以將jvm的整個內(nèi)存鏡像拷貝下來,用于分析每個對象占用的內(nèi)存狀況。當(dāng)你的java進程崩潰了,用這個方法,可以分析出哪些對象是罪魁禍?zhǔn)?/font> § jstack 用于查看java進程id的堆棧信息 用法:jstack 進程id 這個工具對于查看死循環(huán)的線程很有效,可以直接找出是哪個線程在哪個方法內(nèi)死循環(huán)了 總結(jié) JVM的參數(shù)有很多,大部分我們都不需要去設(shè)置和優(yōu)化。如果你的程序沒有問題,就不要去折騰。如果你要優(yōu)化,一定要有相應(yīng)的測試流程來支撐。希望能與大家交流多一些JVM方面的優(yōu)化,尤其是實戰(zhàn)方面遇到的問題。我的郵件 ken@ (轉(zhuǎn)載本站文章請注明作者和出處 ken – www. ,請勿用于商業(yè)用途) 參考資料 § JVM參數(shù) http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html § JVM參數(shù)設(shè)置、分析 http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html |
|