JVM優(yōu)化配置
這里首先要說明的是這里提到的JVM是Sun的HotSpot JVM 5和以上的版本。性能優(yōu)化在應(yīng)用方面可以有很多手段,包括Cache,多線程,各種算法等等。通常情況下是不建議在沒有任何統(tǒng)計(jì)和分析的情況下去手動(dòng)配置JVM的參數(shù)來調(diào)整性能,因?yàn)樵?/span>JVM 5以上已經(jīng)作了根據(jù)機(jī)器和OS的情況自動(dòng)配置合適參數(shù)的算法,基本能夠滿足大部分的情況,當(dāng)然這種自動(dòng)適配只是一種通用的方式,如果說真的要達(dá)到最優(yōu),那么還是需要根據(jù)實(shí)際的使用情況來手動(dòng)的配置各種參數(shù)設(shè)置,提高性能。
JVM能夠?qū)π阅墚a(chǎn)生影響的最大部分就是對于內(nèi)存的管理。從jdk 1.5以后內(nèi)存管理和分配有了很多的改善和提高。
內(nèi)存分配以及管理的幾個(gè)基本概念和參數(shù)說明:
Java Hotspot Mode:
server 和 client兩種模式,如果不配置,JVM會(huì)根據(jù)應(yīng)用服務(wù)器硬件配置自動(dòng)選擇模式,server模式啟動(dòng)比較慢,但是運(yùn)行期速度得到了優(yōu)化,client啟動(dòng)比較快,但是運(yùn)行期響應(yīng)沒有server模式的優(yōu)化,適合于個(gè)人PC的服務(wù)開發(fā)和測試。
Garbage Collector Policy:
在Jdk 1.5的時(shí)候已經(jīng)提供了三種GC,除了原來提供的串行GC(SerialGC)以外,還提供了兩種新的GC:ParallelGC和ConcMarkSweepGC。ParallelGC采用了多線程并行管理和回收垃圾對象,提高了回收效率,提高了服務(wù)器的吞吐量,適合于多處理器的服務(wù)器。ConcMarkSweepGC采用的是并發(fā)方式來管理和回收垃圾對象,降低垃圾回收產(chǎn)生的響應(yīng)暫停時(shí)間。這里說一下并發(fā)和并行的區(qū)別,并發(fā)指的是多個(gè)進(jìn)程并行執(zhí)行垃圾回收,那么可以很好的利用多處理器,而并行指的是應(yīng)用程序不需要暫停可以和垃圾回收線程并發(fā)工作。串行GC適合小型應(yīng)用和單處理器系統(tǒng)(無需多線程交互,效率比較高),后兩者適合大型系統(tǒng)。
使用方式就是在參數(shù)配置中增加-XX:+UseParallelGC等方式來設(shè)置。
對于這部分的配置在網(wǎng)上有很多的實(shí)例可以參考,不過最終采用哪一種GC還是要根據(jù)具體的情況來分析和選擇。
Heap:
OOM的各種經(jīng)歷已經(jīng)讓每一個(gè)架構(gòu)師開發(fā)人員看到了了解Heap的重要性。OOM已經(jīng)是Heap的臨界點(diǎn),不得不引起注意,然而Heap對于性能的潛在影響并未被引起重視,不過和GC配置一樣,在沒有對使用情況作仔細(xì)分析和研究的情況下,貿(mào)然的去修改Heap配置,可能適得其反,這里就來看一下Heap的一些概念和對于性能的影響。
我們的應(yīng)用所能夠得到的最大的Heap受三部分因素的制約:數(shù)據(jù)處理模型(32位或者64位操作系統(tǒng)),系統(tǒng)地虛擬內(nèi)存總數(shù)和系統(tǒng)的物理內(nèi)存總數(shù)。首先Heap的大小不能超過不同操作系統(tǒng)的進(jìn)程尋址范圍,當(dāng)前大部分系統(tǒng)最高限度是4G,Windows通常是2G,Linux通常是3G。系統(tǒng)的虛擬內(nèi)存也是分配的依據(jù),首先是不能超過,然后由于操作系統(tǒng)支持硬盤來做部分的虛擬內(nèi)存,如果設(shè)置過大,那么對于應(yīng)用響應(yīng)來說勢必有影響。再則就是要考慮同一臺(tái)服務(wù)器上運(yùn)行多個(gè)Java虛擬機(jī)所消耗的資源總合也不能超過可用資源。就和前面OOM分析中的一樣,其實(shí)由于OS的數(shù)據(jù)處理模型的限制,機(jī)器本身的硬件內(nèi)存資源和虛擬內(nèi)存資源并不一定會(huì)匹配,那么在有限的資源下如何調(diào)整好資源分配,對于應(yīng)用來說尤為重要。
關(guān)于Heap的幾個(gè)參數(shù)設(shè)置:
說了Heap的有限資源問題以后,就來看看如何通過配置去改變JVM對于Heap的分配。下面所說的主要是對于Java Heap的分配,那么在申請了Java Heap以后,剩下的可用資源就會(huì)被使用到Native Heap。
Xms: java heap初始化時(shí)的大小。默認(rèn)情況是機(jī)器物理內(nèi)存的1/64。這個(gè)主要是根據(jù)應(yīng)用啟動(dòng)時(shí)消耗的資源決定,分配少了申請起來會(huì)降低啟動(dòng)速度,分配多了也浪費(fèi)。
Xmx:java heap的最大值,默認(rèn)是機(jī)器物理內(nèi)存的1/4,最大也就到1G。這個(gè)值決定了最多可用的Java Heap Memory,分配過少就會(huì)在應(yīng)用需要大量內(nèi)存作緩存或者零時(shí)對象時(shí)出現(xiàn)OOM的問題,如果分配過大,那么就會(huì)產(chǎn)生上文提到的第二類OOM。所以如何配置還是根據(jù)運(yùn)行過程中的分析和計(jì)算來確定,如果不能確定還是采用默認(rèn)的配置。
Xmn:java heap新生代的空間大小。在GC模型中,根據(jù)對象的生命周期的長短,產(chǎn)生了內(nèi)存分代的設(shè)計(jì):青年代(內(nèi)部也分成三部分,類似于整體劃分的作用,可以通過配置來設(shè)置比例),老年代,持久代。每一代的管理和回收策略都不相同,最為活躍的就是青年代,同時(shí)這部分的內(nèi)存分配和管理效率也是最高。通常情況下,對于內(nèi)存的申請優(yōu)先在新生代中申請,當(dāng)內(nèi)存不夠時(shí)會(huì)整理新生代,當(dāng)整理以后還是不能滿足申請的內(nèi)存,就會(huì)向老年代移動(dòng)一些生命周期較長的對象。這種整理和移動(dòng)會(huì)消耗資源,同時(shí)降低系統(tǒng)運(yùn)行響應(yīng)能力,因此如果青年代設(shè)置的過小,就會(huì)頻繁的整理和移動(dòng),對性能造成影響。那是否把年青代設(shè)置的越大越好,其實(shí)不然,年青代采用的是復(fù)制搜集算法,這種算法必須停止所有應(yīng)用程序線程,服務(wù)器線程切換時(shí)間就會(huì)成為應(yīng)用響應(yīng)的瓶頸(當(dāng)然永遠(yuǎn)不用收集那么就不存在這個(gè)問題)。老年代采用的是串行標(biāo)記收集的方式,并發(fā)收集可以減少對于應(yīng)用的影響。
Xss:線程堆棧最大值。允許更多的虛擬內(nèi)存空間地址被Java Heap使用。
以下是sun公司的性能優(yōu)化白皮書中提到的幾個(gè)例子:
1.對于吞吐量的調(diào)優(yōu)。機(jī)器配置:4G的內(nèi)存,32個(gè)線程并發(fā)能力。
java
-Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20
-Xmx3800m -Xms3800m
配置了最大Java Heap來充分利用系統(tǒng)內(nèi)存。
-Xmn2g
創(chuàng)建足夠大的青年代(可以并行被回收)充分利用系統(tǒng)內(nèi)存,防止將短期對象復(fù)制到老年代。
-Xss128
減少默認(rèn)最大的線程棧大小,提供更多的處理虛擬內(nèi)存地址空間被進(jìn)程使用。
-XX:+UseParallelGC
采用并行垃圾收集器對年青代的內(nèi)存進(jìn)行收集,提高效率。
-XX:ParallelGCThreads=20
減少垃圾收集線程,默認(rèn)是和服務(wù)器可支持的線程最大并發(fā)數(shù)相同,往往不需要配置到最大值。
2
.嘗試采用對老年代并行收集
java
-Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC
-Xmx3550m -Xms3550m
內(nèi)存分配被減小,因?yàn)镻arallelOldGC會(huì)增加對于Native Heap的需求,因此需要減小Java Heap來滿足需求。
-XX:+UseParallelOldGC
采用對于老年代并發(fā)收集的策略,可以提高收集效率。
3
.提高吞吐量,減少應(yīng)用停頓時(shí)間
java
-Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC
選擇了并發(fā)標(biāo)記交換收集器,它可以并發(fā)執(zhí)行收集操作,降低應(yīng)用停止時(shí)間,同時(shí)它也是并行處理模式,可以有效地利用多處理器的系統(tǒng)的多進(jìn)程處理。
-XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=31
表示在青年代中Eden和Survivor比例,設(shè)置增加了Survivor的大小,越大的survivor空間可以允許短期對象盡量在年青代消亡。
-XX:TargetSurvivorRatio=90
允許90%的空間被占用,超過默認(rèn)的50%,提高對于survivor的使用率。
類似的例子網(wǎng)上很多,這兒就不在列下來了,最終是否采取自己配置來替換默認(rèn)配置還是要根據(jù)虛擬機(jī)的使用情況來分析和配置。