今天就跟大家聊聊有關(guān)如何合理的規(guī)劃一次JVM性能調(diào)優(yōu),可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
10年的洛川網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都營銷網(wǎng)站建設(shè)的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整洛川建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“洛川網(wǎng)站設(shè)計(jì)”,“洛川網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
摘要: JVM性能調(diào)優(yōu)涉及到方方面面的取舍,往往是牽一發(fā)而動(dòng)全身,需要全盤考慮各方面的影響,那么如何進(jìn)行一次優(yōu)雅的調(diào)優(yōu),提升應(yīng)用的性能?
JVM性能調(diào)優(yōu)涉及到方方面面的取舍,往往是牽一發(fā)而動(dòng)全身,需要全盤考慮各方面的影響。但也有一些基礎(chǔ)的理論和原則,理解這些理論并遵循這些原則會(huì)讓你的性能調(diào)優(yōu)任務(wù)將會(huì)更加輕松。為了更好的理解本篇所介紹的內(nèi)容。你需要已經(jīng)了解和遵循以下內(nèi)容:
1、已了解jvm 垃圾收集器
2、已了解jvm 性能監(jiān)控常用工具
3、能夠讀懂gc日志
4、確信不為了調(diào)優(yōu)而調(diào)優(yōu),jvm調(diào)優(yōu)不能解決一切性能問題
這些內(nèi)容在之前的兩篇文章已經(jīng)介紹過了,如果有不了解的可以去點(diǎn)擊上述連接進(jìn)行回顧,如果對(duì)這些不了解不建議讀本篇文章。
為了提升系統(tǒng)性能,我們需要對(duì)系統(tǒng)的各個(gè)角度和層次來進(jìn)行優(yōu)化,以下是需要優(yōu)化的幾個(gè)層次。
從上面我們可以看到,除了jvm調(diào)優(yōu)以外,還有其他幾個(gè)層面需要來處理,所以針對(duì)系統(tǒng)的調(diào)優(yōu)不是只有jvm調(diào)優(yōu)一項(xiàng),而是需要針對(duì)系統(tǒng)來整體調(diào)優(yōu),才能提升系統(tǒng)的性能。本篇只針對(duì)jvm調(diào)優(yōu)來講解,其他幾個(gè)方面,后續(xù)再介紹。
在進(jìn)行jvm調(diào)優(yōu)之前,我們假設(shè)項(xiàng)目的架構(gòu)調(diào)優(yōu)和代碼調(diào)優(yōu)已經(jīng)進(jìn)行過或者是針對(duì)當(dāng)前項(xiàng)目是最優(yōu)的。這兩個(gè)是jvm調(diào)優(yōu)的基礎(chǔ),并且架構(gòu)調(diào)優(yōu)是對(duì)系統(tǒng)影響最大的 ,我們不能指望一個(gè)系統(tǒng)架構(gòu)有缺陷或者代碼層次優(yōu)化沒有窮盡的應(yīng)用,通過jvm調(diào)優(yōu)令其達(dá)到一個(gè)質(zhì)的飛躍,這是不可能的。
另外,在調(diào)優(yōu)之前,必須得有明確的性能優(yōu)化目標(biāo), 然后找到其性能瓶頸。之后針對(duì)瓶頸的優(yōu)化,還需要對(duì)應(yīng)用進(jìn)行壓力和基準(zhǔn)測試,通過各種監(jiān)控和統(tǒng)計(jì)工具,確認(rèn)調(diào)優(yōu)后的應(yīng)用是否已經(jīng)達(dá)到相關(guān)目標(biāo)。
調(diào)優(yōu)的最終目的都是為了令應(yīng)用程序使用最小的硬件消耗來承載更大的吞吐。jvm的調(diào)優(yōu)也不例外,jvm調(diào)優(yōu)主要是針對(duì)垃圾收集器的收集性能優(yōu)化,令運(yùn)行在虛擬機(jī)上的應(yīng)用能夠使用更少的內(nèi)存以及延遲獲取更大的吞吐量。當(dāng)然這里的最少是最優(yōu)的選擇,而不是越少越好。
1、性能定義
要查找和評(píng)估器性能瓶頸,首先要知道性能定義,對(duì)于jvm調(diào)優(yōu)來說,我們需要知道以下三個(gè)定義屬性,依作為評(píng)估基礎(chǔ):
吞吐量:重要指標(biāo)之一,是指不考慮垃圾收集引起的停頓時(shí)間或內(nèi)存消耗,垃圾收集器能支撐應(yīng)用達(dá)到的最高性能指標(biāo)。
延遲:其度量標(biāo)準(zhǔn)是縮短由于垃圾啊收集引起的停頓時(shí)間或者完全消除因垃圾收集所引起的停頓,避免應(yīng)用運(yùn)行時(shí)發(fā)生抖動(dòng)。
內(nèi)存占用:垃圾收集器流暢運(yùn)行所需要 的內(nèi)存數(shù)量。
這三個(gè)屬性中,其中一個(gè)任何一個(gè)屬性性能的提高,幾乎都是以另外一個(gè)或者兩個(gè)屬性性能的損失作代價(jià),不可兼得,具體某一個(gè)屬性或者兩個(gè)屬性的性能對(duì)應(yīng)用來說比較重要,要基于應(yīng)用的業(yè)務(wù)需求來確定。
2、性能調(diào)優(yōu)原則
在調(diào)優(yōu)過程中,我們應(yīng)該謹(jǐn)記以下3個(gè)原則,以便幫助我們更輕松的完成垃圾收集的調(diào)優(yōu),從而達(dá)到應(yīng)用程序的性能要求。
MinorGC回收原則: 每次minor GC 都要盡可能多的收集垃圾對(duì)象。以減少應(yīng)用程序發(fā)生Full GC的頻率。
GC內(nèi)存最大化原則:處理吞吐量和延遲問題時(shí)候,垃圾處理器能使用的內(nèi)存越大,垃圾收集的效果越好,應(yīng)用程序也會(huì)越來越流暢。
GC調(diào)優(yōu)3選2原則: 在性能屬性里面,吞吐量、延遲、內(nèi)存占用,我們只能選擇其中兩個(gè)進(jìn)行調(diào)優(yōu),不可三者兼得。
3、性能調(diào)優(yōu)流程
以上就是對(duì)應(yīng)用程序進(jìn)行jvm調(diào)優(yōu)的基本流程,我們可以看到,jvm調(diào)優(yōu)是根據(jù)性能測試結(jié)果不斷優(yōu)化配置而多次迭代的過程。在達(dá)到每一個(gè)系統(tǒng)需求指標(biāo)之前,之前的每個(gè)步驟都有可能經(jīng)歷多次迭代。有時(shí)候?yàn)榱诉_(dá)到某一方面的指標(biāo),有可能需要對(duì)之前的參數(shù)進(jìn)行多次調(diào)整,進(jìn)而需要把之前的所有步驟重新測試一遍。
另外調(diào)優(yōu)一般是從滿足程序的內(nèi)存使用需求開始的,之后是時(shí)間延遲的要求,最后才是吞吐量的要求,要基于這個(gè)步驟來不斷優(yōu)化,每一個(gè)步驟都是進(jìn)行下一步的基礎(chǔ),不可逆行之。以下我們針對(duì)每個(gè)步驟進(jìn)行詳細(xì)的示例講解。
在JVM的運(yùn)行模式方面,我們直接選擇server模式,這也是jdk1.6以后官方推薦的模式。
在垃圾收集器方面,我們直接采用了jdk1.6-1.8 中默認(rèn)的parallel收集器(新生代采用parallelGC,老生代采用parallelOldGC)。
在確定內(nèi)存占用之前,我們需要知道兩個(gè)知識(shí)點(diǎn):
應(yīng)用程序的運(yùn)行階段
jvm內(nèi)存分配
1、運(yùn)行階段
應(yīng)用程序的運(yùn)行階段,我可以劃分為以下三個(gè)階段:
1、初始化階段 : jvm加載應(yīng)用程序,初始化應(yīng)用程序的主要模塊和數(shù)據(jù)。
2、穩(wěn)定階段:應(yīng)用在此時(shí)運(yùn)行了大多數(shù)時(shí)間,經(jīng)歷過壓力測試的之后,各項(xiàng)性能參數(shù)呈穩(wěn)定狀態(tài)。核心函數(shù)被執(zhí)行,已經(jīng)被jit編譯預(yù)熱過。
3、總結(jié)階段:最后的總結(jié)階段,進(jìn)行一些基準(zhǔn)測試,生成響應(yīng)的策報(bào)告。這個(gè)階段我們可以不關(guān)注。
確定內(nèi)存占用以及活躍數(shù)據(jù)的大小,我們應(yīng)該是在程序的穩(wěn)定階段來進(jìn)行確定,而不是在項(xiàng)目起初階段來進(jìn)行確定,如何確定,我們先看以下jvm的內(nèi)存分配。
2、jvm內(nèi)存分配&參數(shù)
jvm堆中主要的空間,就是以上新生代、老生代、永久代組成,整個(gè)堆大小=新生代大小 + 老生代大小 + 永久代大小。 具體的對(duì)象提升方式,這里不再過多介紹了,我們看下一些jvm命令參數(shù),對(duì)堆大小的指定。如果不采用以下參數(shù)進(jìn)行指定的話,虛擬機(jī)會(huì)自動(dòng)選擇合適的值,同時(shí)也會(huì)基于系統(tǒng)的開銷自動(dòng)調(diào)整。
分代
參數(shù)
描述
堆大小
-Xms
初始堆大小,默認(rèn)為物理內(nèi)存的1/64(<1GB)
-Xmx
最大堆大小,默認(rèn)(MaxHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存大于70%時(shí),JVM會(huì)減少堆直到 -Xms的最小限制
新生代
-XX:NewSize
新生代空間大小初始值
-XX:MaxNewSize
新生代空間大小最大值
-Xmn
新生代空間大小,此處的大小是(eden+2 survivor space)
永久代
-XX:PermSize
永久代空間的初始值&最小值
-XX:MaxPermSize
永久代空間的最大值
老年代
老年代的空間大小會(huì)根據(jù)新生代的大小隱式設(shè)定
初始值=-Xmx減去-XX:NewSize的值
最小值=-Xmx值減去-XX:MaxNewSize的值
在設(shè)置的時(shí)候,如果關(guān)注性能開銷的話,應(yīng)盡量把永久代的初始值與最大值設(shè)置為同一值,因?yàn)橛谰么拇笮≌{(diào)整需要進(jìn)行FullGC 才能實(shí)現(xiàn)。
3、計(jì)算活躍數(shù)據(jù)大小
計(jì)算活躍數(shù)據(jù)大小應(yīng)該遵循以下流程:
如前所述,活躍數(shù)據(jù)應(yīng)該是基于應(yīng)用程序穩(wěn)定階段時(shí),觀察長期存活與對(duì)象在java堆中占用的空間大小。
計(jì)算活躍數(shù)據(jù)時(shí)應(yīng)該確保以下條件發(fā)生:
1.測試時(shí),啟動(dòng)參數(shù)采用jvm默認(rèn)參數(shù),不人為設(shè)置。
2.確保Full GC 發(fā)生時(shí),應(yīng)用程序正處于穩(wěn)定階段。
采用jvm默認(rèn)參數(shù)啟動(dòng),是為了觀察應(yīng)用程序在穩(wěn)定階段的所需要的內(nèi)存使用。
如何才算穩(wěn)定階段?
一定得需要產(chǎn)生足夠的壓力,找到應(yīng)用程序和生產(chǎn)環(huán)境高峰符合狀態(tài)類似的負(fù)荷,在此之后達(dá)到峰值之后,保持一個(gè)穩(wěn)定的狀態(tài),才算是一個(gè)穩(wěn)定階段。所以要達(dá)到穩(wěn)定階段,壓力測試是必不可少的,具體如何如何對(duì)應(yīng)用壓力測試,本篇不過多說明,后期會(huì)有專門介紹的篇幅。
在確定了應(yīng)用出于穩(wěn)定階段的時(shí)候,要注意觀察應(yīng)用的GC日志,特別是Full GC 日志。
GC日志指令: -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:
GC日志是收集調(diào)優(yōu)所需信息的最好途徑,即便是在生產(chǎn)環(huán)境,也可以開啟GC日志來定位問題,開啟GC日志對(duì)性能的影響極小,卻可以提供豐富數(shù)據(jù)。
必須得有FullGC 日志,如果沒有的話,可以采用監(jiān)控工具強(qiáng)制調(diào)用一次,或者采用以下命令,亦可以觸發(fā)
jmap -histo:live pid
在穩(wěn)定階段觸發(fā)了FullGC我們一般會(huì)拿到如下信息:
從以上gc日志中,我們大概可以分析到,在發(fā)生fullGC之時(shí),整個(gè)應(yīng)用的堆占用以及GC時(shí)間,當(dāng)然了,為了更加精確,應(yīng)該多收集幾次,獲取一個(gè)平均值。或者是采用耗時(shí)最長的一次FullGC來進(jìn)行估算。
在上圖中,fullGC之后,老年代空間占用在93168kb(約93MB),我們以此定為老年代空間的活躍數(shù)據(jù)。
其他堆空間的分配,基于以下規(guī)則來進(jìn)行。
空間
命令參數(shù)
建議擴(kuò)大倍數(shù)
java heap
-Xms和-Xmx
3-4倍FullGC后的老年代空間占用
永久代
-XX:PermSize
-XX:MaxPermSize
1.2-1.5倍FullGc后的永久帶空間占用
新生代
-Xmn
1-1.5倍FullGC之后的老年代空間占用
老年代
2-3倍FullGC后的老年代空間占用
基于以上規(guī)則和上圖中的FullGC信息,我們現(xiàn)在可以規(guī)劃的該應(yīng)用堆空間為:
java 堆空間: 373Mb (=老年代空間93168kb*4)
新生代空間:140Mb(=老年代空間93168kb*1.5)
永久代空間:5Mb(=永久代空間3135kb*1.5)
老年代空間: 233Mb=堆空間-新生代看空間=373Mb-140Mb
對(duì)應(yīng)的應(yīng)用啟動(dòng)參數(shù)應(yīng)該為:
java -Xms373m -Xmx373m -Xmn140m -XX:PermSize=5m -XX:MaxPermSize=5m
在確定了應(yīng)用程序的活躍數(shù)據(jù)大小之后,我們需要再進(jìn)行延遲性調(diào)優(yōu),因?yàn)閷?duì)于此時(shí)堆內(nèi)存大小,延遲性需求無法達(dá)到應(yīng)用的需要,需要基于應(yīng)用的情況來進(jìn)行調(diào)試。
在這一步進(jìn)行期間,我們可能會(huì)再次優(yōu)化堆大小的配置,評(píng)估GC的持續(xù)時(shí)間和頻率、以及是否需要切換到不同的垃圾收集器上。
1、系統(tǒng)延遲需求
在調(diào)優(yōu)之前,我們需要知道系統(tǒng)的延遲需求是那些,以及對(duì)應(yīng)的延遲可調(diào)優(yōu)指標(biāo)是那些。
應(yīng)用程序可接受的平均停滯時(shí)間: 此時(shí)間與測量的Minor GC持續(xù)時(shí)間進(jìn)行比較。
可接受的Minor GC頻率:Minor GC的頻率與可容忍的值進(jìn)行比較。
可接受的最大停頓時(shí)間: 最大停頓時(shí)間與最差情況下FullGC的持續(xù)時(shí)間進(jìn)行比較。
可接受的最大停頓發(fā)生的頻率:基本就是FullGC的頻率。
以上中,平均停滯時(shí)間和最大停頓時(shí)間,對(duì)用戶體驗(yàn)最為重要,可以多關(guān)注。
基于以上的要求,我們需要統(tǒng)計(jì)以下數(shù)據(jù):
MinorGC的持續(xù)時(shí)間;
統(tǒng)計(jì)MinorGC的次數(shù);
FullGC的最差持續(xù)時(shí)間;
最差情況下,F(xiàn)ullGC的頻率;
2、優(yōu)化新生代的大小
比如如上的gc日志中,我們可以看到Minor GC的平均持續(xù)時(shí)間=0.069秒,MinorGC 的頻率為0.389秒一次。
如果,我們系統(tǒng)的設(shè)置的平均停滯時(shí)間為50ms,當(dāng)前的69ms明顯是太長了,就需要調(diào)整。
我們知道新生代空間越大,Minor GC的GC時(shí)間越長,頻率越低。
如果想減少其持續(xù)時(shí)長,就需要減少其空間大小。
如果想減小其頻率,就需要加大其空間大小。
為了降低改變新生代的大小對(duì)其他區(qū)域的最小影響。在改變新生代空間大小的時(shí)候,盡量保持老年代空間的大小。
比如此次減少了新生代空間10%的大小,應(yīng)該保持老年代和持代的大小不變化,第一步調(diào)優(yōu)后的參數(shù)如下變化:
java -Xms359m -Xmx359m -Xmn126m -XX:PermSize=5m -XX:MaxPermSize=5m
新生代的大小有140m變?yōu)?26,堆大小順應(yīng)變化,此時(shí)老年代是沒有變化的。
3、優(yōu)化老年代的大小
同上一步一樣,在優(yōu)化之前,也需要采集gc日志的數(shù)據(jù)。此次我們關(guān)注的是FullGC的持續(xù)時(shí)間和頻率。
上圖中,我們可以看到
FullGC 平均頻率 =5.8s
FullGC 平均持續(xù)時(shí)間=0.14s
(以上為了測試,真實(shí)項(xiàng)目的fullGC 沒有這么快)
如果沒有FullGC的日志,有辦法可以評(píng)估么?
我們可以通過對(duì)象提升率進(jìn)行計(jì)算。
對(duì)象提升率
比如上述中啟動(dòng)參數(shù)中,我們的老年代大小=233Mb。
那么需要多久才能填滿老年代中這233Mb的空閑空間取決于新生代到老年代的提升率。
每次提升老年代占用量=每次MinorGC 之后 java堆占用情況 減去 MinorGC后新生代的空間占用
對(duì)象提升率=平均值(每次提升老年代占用量) 除以 老年代空間
有了對(duì)象提升率,我們就可以算出填充滿老年代空間需要多少次minorGC,大概一次fullGC的時(shí)間就可以計(jì)算出來了。
比如:
上圖中:
第一次minor GC 之后,老年代空間:13740kb - 13732kb =8kb
第二次minor GC 之后,老年代空間:22394kb - 17905kb =4489kb
第三次minor GC 之后,老年代空間:34739kb - 17917kb =16822kb
第四次minor GC 之后,老年代空間:48143kb - 17913kb =30230kb
第五次minor GC 之后,老年代空間:62112kb - 17917kb =44195kb
老年代每次minorGC提升率
4481kb 第二次和第一次minorGC之間
12333kb 第3次和第2次minorGC之間
13408kb 第4次和第3次minorGC之間
13965kb 第5次和第4次minorGC之間
我們可以測算出:
每次minorGC 的平均提升為12211kb,約為12Mb
上圖中,平均minorGC的頻率為 213ms/次
提升率=12211kb/213ms=57kb/ms
老年代空間233Mb ,占滿大概需要233*1024/57=4185ms 約為4.185s。
FullGC的預(yù)期最差頻率時(shí)長可以通過以上兩種方式估算出來,可以調(diào)整老年代的大小來調(diào)整FullGC的頻率,當(dāng)然了,如果FullGC持續(xù)時(shí)間過長,無法達(dá)到應(yīng)用程序的最差延遲要求,就需要切換垃圾處理器了。具體如何切換,下篇再講,比如切換為CMS,針對(duì)CMS的調(diào)優(yōu)方式又有會(huì)細(xì)微的差別。
經(jīng)過上述漫長 調(diào)優(yōu)過程,最終來到了調(diào)優(yōu)的最后一步,這一步對(duì)上述的結(jié)果進(jìn)行吞吐量測試,并進(jìn)行微調(diào)。
吞吐量調(diào)優(yōu)主要是基于應(yīng)用程序的吞吐量要求而來的,應(yīng)用程序應(yīng)該有一個(gè)綜合的吞吐指標(biāo),這個(gè)指標(biāo)基于真?zhèn)€應(yīng)用的需求和測試而衍生出來的。當(dāng)有應(yīng)用程序的吞吐量達(dá)到或者超過預(yù)期的吞吐目標(biāo),整個(gè)調(diào)優(yōu)過程就可以圓滿結(jié)束了。
如果出現(xiàn)調(diào)優(yōu)后依然無法達(dá)到應(yīng)用程序的吞吐目標(biāo),需要重新回顧吞吐要求,評(píng)估當(dāng)前吞吐量和目標(biāo)差距是否巨大,如果在20%左右,可以修改參數(shù),加大內(nèi)存,再次從頭調(diào)試,如果巨大就需要從整個(gè)應(yīng)用層面來考慮,設(shè)計(jì)以及目標(biāo)是否一致了,重新評(píng)估吞吐目標(biāo)。
對(duì)于垃圾收集器來說,提升吞吐量的性能調(diào)優(yōu)的目標(biāo)就是就是盡可能避免或者很少發(fā)生FullGC 或者Stop-The-World壓縮式垃圾收集(CMS),因?yàn)檫@兩種方式都會(huì)造成應(yīng)用程序吞吐降低。盡量在MinorGC 階段回收更多的對(duì)象,避免對(duì)象提升過快到老年代。
據(jù)Plumbr公司對(duì)特定垃圾收集器使用情況進(jìn)行了一次調(diào)查研究,研究數(shù)據(jù)使用了84936個(gè)案例。在明確指定垃圾收集器的13%的案例中,并發(fā)收集器(CMS)使用次數(shù)最多;但大多數(shù)案例沒有選擇最佳垃圾收集器。這個(gè)比例占用在87%左右。
JVM調(diào)優(yōu)是一個(gè)系統(tǒng)而又復(fù)雜的工作,目前jvm下的自動(dòng)調(diào)整已經(jīng)做的比較優(yōu)秀,基本的一些初始參數(shù)都可以保證一般的應(yīng)用跑的比較穩(wěn)定了,對(duì)部分團(tuán)隊(duì)來說,程序性能可能優(yōu)先級(jí)不高,默認(rèn)垃圾收集器已經(jīng)夠用了。調(diào)優(yōu)要基于自己的情況而來。
看完上述內(nèi)容,你們對(duì)如何合理的規(guī)劃一次JVM性能調(diào)優(yōu)有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。
本文題目:如何合理的規(guī)劃一次JVM性能調(diào)優(yōu)
當(dāng)前網(wǎng)址:http://aaarwkj.com/article14/pdhgge.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、企業(yè)網(wǎng)站制作、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站策劃、建站公司、品牌網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)