自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何合理的規(guī)劃JVM性能調(diào)優(yōu)

云計算 虛擬化
JVM性能調(diào)優(yōu)涉及到方方面面的取舍,往往是牽一發(fā)而動全身,需要全盤考慮各方面的影響。但也有一些基礎(chǔ)的理論和原則,理解這些理論并遵循這些原則會讓你的性能調(diào)優(yōu)任務(wù)將會更加輕松。為了更好的理解本篇所介紹的內(nèi)容。

 JVM性能調(diào)優(yōu)涉及到方方面面的取舍,往往是牽一發(fā)而動全身,需要全盤考慮各方面的影響。但也有一些基礎(chǔ)的理論和原則,理解這些理論并遵循這些原則會讓你的性能調(diào)優(yōu)任務(wù)將會更加輕松。為了更好的理解本篇所介紹的內(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)不能解決一切性能問題

如果對這些不了解不建議讀本篇文章。

[[257523]]

本篇文章基于jvm性能調(diào)優(yōu),結(jié)合jvm的各項參數(shù)對應(yīng)用程序調(diào)優(yōu),主要內(nèi)容有以下幾個方面:

1、jvm調(diào)優(yōu)的一般流程

2、jvm調(diào)優(yōu)所要關(guān)注的幾個性能指標(biāo)

3、jvm調(diào)優(yōu)需要掌握的一些原則

4、調(diào)優(yōu)策略&示例

一、性能調(diào)優(yōu)的層次

為了提升系統(tǒng)性能,我們需要對系統(tǒng)的各個角度和層次來進(jìn)行優(yōu)化,以下是需要優(yōu)化的幾個層次。

 

從上面我們可以看到,除了jvm調(diào)優(yōu)以外,還有其他幾個層面需要來處理,所以針對系統(tǒng)的調(diào)優(yōu)不是只有jvm調(diào)優(yōu)一項,而是需要針對系統(tǒng)來整體調(diào)優(yōu),才能提升系統(tǒng)的性能。本篇只針對jvm調(diào)優(yōu)來講解,其他幾個方面,后續(xù)再介紹。

在進(jìn)行jvm調(diào)優(yōu)之前,我們假設(shè)項目的架構(gòu)調(diào)優(yōu)和代碼調(diào)優(yōu)已經(jīng)進(jìn)行過或者是針對當(dāng)前項目是***的。這兩個是jvm調(diào)優(yōu)的基礎(chǔ),并且架構(gòu)調(diào)優(yōu)是對系統(tǒng)影響***的 ,我們不能指望一個系統(tǒng)架構(gòu)有缺陷或者代碼層次優(yōu)化沒有窮盡的應(yīng)用,通過jvm調(diào)優(yōu)令其達(dá)到一個質(zhì)的飛躍,這是不可能的。

另外,在調(diào)優(yōu)之前,必須得有明確的性能優(yōu)化目標(biāo), 然后找到其性能瓶頸。之后針對瓶頸的優(yōu)化,還需要對應(yīng)用進(jìn)行壓力和基準(zhǔn)測試,通過各種監(jiān)控和統(tǒng)計工具,確認(rèn)調(diào)優(yōu)后的應(yīng)用是否已經(jīng)達(dá)到相關(guān)目標(biāo)。

二、jvm調(diào)優(yōu)流程

調(diào)優(yōu)的最終目的都是為了令應(yīng)用程序使用最小的硬件消耗來承載更大的吞吐。jvm的調(diào)優(yōu)也不例外,jvm調(diào)優(yōu)主要是針對垃圾收集器的收集性能優(yōu)化,令運(yùn)行在虛擬機(jī)上的應(yīng)用能夠使用更少的內(nèi)存以及延遲獲取更大的吞吐量。當(dāng)然這里的最少是***的選擇,而不是越少越好。

1、性能定義

要查找和評估器性能瓶頸,首先要知道性能定義,對于jvm調(diào)優(yōu)來說,我們需要知道以下三個定義屬性,依作為評估基礎(chǔ):

  • 吞吐量:重要指標(biāo)之一,是指不考慮垃圾收集引起的停頓時間或內(nèi)存消耗,垃圾收集器能支撐應(yīng)用達(dá)到的***性能指標(biāo)。
  • 延遲:其度量標(biāo)準(zhǔn)是縮短由于垃圾啊收集引起的停頓時間或者完全消除因垃圾收集所引起的停頓,避免應(yīng)用運(yùn)行時發(fā)生抖動。
  • 內(nèi)存占用:垃圾收集器流暢運(yùn)行所需要 的內(nèi)存數(shù)量。

這三個屬性中,其中一個任何一個屬性性能的提高,幾乎都是以另外一個或者兩個屬性性能的損失作代價,不可兼得,具體某一個屬性或者兩個屬性的性能對應(yīng)用來說比較重要,要基于應(yīng)用的業(yè)務(wù)需求來確定。

2、性能調(diào)優(yōu)原則

在調(diào)優(yōu)過程中,我們應(yīng)該謹(jǐn)記以下3個原則,以便幫助我們更輕松的完成垃圾收集的調(diào)優(yōu),從而達(dá)到應(yīng)用程序的性能要求。

1. MinorGC回收原則: 每次minor GC 都要盡可能多的收集垃圾對象。以減少應(yīng)用程序發(fā)生Full GC的頻率。

2. GC內(nèi)存***化原則:處理吞吐量和延遲問題時候,垃圾處理器能使用的內(nèi)存越大,垃圾收集的效果越好,應(yīng)用程序也會越來越流暢。

3. GC調(diào)優(yōu)3選2原則: 在性能屬性里面,吞吐量、延遲、內(nèi)存占用,我們只能選擇其中兩個進(jìn)行調(diào)優(yōu),不可三者兼得。

3、性能調(diào)優(yōu)流程

 

以上就是對應(yīng)用程序進(jìn)行jvm調(diào)優(yōu)的基本流程,我們可以看到,jvm調(diào)優(yōu)是根據(jù)性能測試結(jié)果不斷優(yōu)化配置而多次迭代的過程。在達(dá)到每一個系統(tǒng)需求指標(biāo)之前,之前的每個步驟都有可能經(jīng)歷多次迭代。有時候為了達(dá)到某一方面的指標(biāo),有可能需要對之前的參數(shù)進(jìn)行多次調(diào)整,進(jìn)而需要把之前的所有步驟重新測試一遍。

另外調(diào)優(yōu)一般是從滿足程序的內(nèi)存使用需求開始的,之后是時間延遲的要求,***才是吞吐量的要求,要基于這個步驟來不斷優(yōu)化,每一個步驟都是進(jìn)行下一步的基礎(chǔ),不可逆行之。以下我們針對每個步驟進(jìn)行詳細(xì)的示例講解。

在JVM的運(yùn)行模式方面,我們直接選擇server模式,這也是jdk1.6以后官方推薦的模式。

在垃圾收集器方面,我們直接采用了jdk1.6-1.8 中默認(rèn)的parallel收集器(新生代采用parallelGC,老生代采用parallelOldGC)。

三、確定內(nèi)存占用

在確定內(nèi)存占用之前,我們需要知道兩個知識點:

  • 應(yīng)用程序的運(yùn)行階段
  • jvm內(nèi)存分配

1、運(yùn)行階段

應(yīng)用程序的運(yùn)行階段,我可以劃分為以下三個階段:

1、初始化階段 : jvm加載應(yīng)用程序,初始化應(yīng)用程序的主要模塊和數(shù)據(jù)。

2、穩(wěn)定階段:應(yīng)用在此時運(yùn)行了大多數(shù)時間,經(jīng)歷過壓力測試的之后,各項性能參數(shù)呈穩(wěn)定狀態(tài)。核心函數(shù)被執(zhí)行,已經(jīng)被jit編譯預(yù)熱過。

3、總結(jié)階段:***的總結(jié)階段,進(jìn)行一些基準(zhǔn)測試,生成響應(yīng)的策報告。這個階段我們可以不關(guān)注。

確定內(nèi)存占用以及活躍數(shù)據(jù)的大小,我們應(yīng)該是在程序的穩(wěn)定階段來進(jìn)行確定,而不是在項目起初階段來進(jìn)行確定,如何確定,我們先看以下jvm的內(nèi)存分配。

2、jvm內(nèi)存分配&參數(shù)

 

jvm堆中主要的空間,就是以上新生代、老生代、***代組成,整個堆大小=新生代大小 + 老生代大小 + ***代大小。 具體的對象提升方式,這里不再過多介紹了,我們看下一些jvm命令參數(shù),對堆大小的指定。如果不采用以下參數(shù)進(jìn)行指定的話,虛擬機(jī)會自動選擇合適的值,同時也會基于系統(tǒng)的開銷自動調(diào)整。

 

在設(shè)置的時候,如果關(guān)注性能開銷的話,應(yīng)盡量把***代的初始值與***值設(shè)置為同一值,因為***代的大小調(diào)整需要進(jìn)行FullGC 才能實現(xiàn)。

3、計算活躍數(shù)據(jù)大小

計算活躍數(shù)據(jù)大小應(yīng)該遵循以下流程:

 

如前所述,活躍數(shù)據(jù)應(yīng)該是基于應(yīng)用程序穩(wěn)定階段時,觀察長期存活與對象在java堆中占用的空間大小。

計算活躍數(shù)據(jù)時應(yīng)該確保以下條件發(fā)生:

1.測試時,啟動參數(shù)采用jvm默認(rèn)參數(shù),不人為設(shè)置。

2.確保Full GC 發(fā)生時,應(yīng)用程序正處于穩(wěn)定階段。

采用jvm默認(rèn)參數(shù)啟動,是為了觀察應(yīng)用程序在穩(wěn)定階段的所需要的內(nèi)存使用。

如何才算穩(wěn)定階段?

一定得需要產(chǎn)生足夠的壓力,找到應(yīng)用程序和生產(chǎn)環(huán)境高峰符合狀態(tài)類似的負(fù)荷,在此之后達(dá)到峰值之后,保持一個穩(wěn)定的狀態(tài),才算是一個穩(wěn)定階段。所以要達(dá)到穩(wěn)定階段,壓力測試是必不可少的,具體如何如何對應(yīng)用壓力測試,本篇不過多說明,后期會有專門介紹的篇幅。

在確定了應(yīng)用出于穩(wěn)定階段的時候,要注意觀察應(yīng)用的GC日志,特別是Full GC 日志。

GC日志指令: -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:

GC日志是收集調(diào)優(yōu)所需信息的***途徑,即便是在生產(chǎn)環(huán)境,也可以開啟GC日志來定位問題,開啟GC日志對性能的影響極小,卻可以提供豐富數(shù)據(jù)。

必須得有FullGC 日志,如果沒有的話,可以采用監(jiān)控工具強(qiáng)制調(diào)用一次,或者采用以下命令,亦可以觸發(fā)

  1. jmap -histo:live pid 

在穩(wěn)定階段觸發(fā)了FullGC我們一般會拿到如下信息:

 

從以上gc日志中,我們大概可以分析到,在發(fā)生fullGC之時,整個應(yīng)用的堆占用以及GC時間,當(dāng)然了,為了更加精確,應(yīng)該多收集幾次,獲取一個平均值?;蛘呤遣捎煤臅r最長的一次FullGC來進(jìn)行估算。

在上圖中,fullGC之后,老年代空間占用在93168kb(約93MB),我們以此定為老年代空間的活躍數(shù)據(jù)。

其他堆空間的分配,基于以下規(guī)則來進(jìn)行。

 

基于以上規(guī)則和上圖中的FullGC信息,我們現(xiàn)在可以規(guī)劃的該應(yīng)用堆空間為:

java 堆空間: 373Mb (=老年代空間93168kb*4)

新生代空間:140Mb(=老年代空間93168kb*1.5)

***代空間:5Mb(=***代空間3135kb*1.5)

老年代空間: 233Mb=堆空間-新生代看空間=373Mb-140Mb

對應(yīng)的應(yīng)用啟動參數(shù)應(yīng)該為:

java -Xms373m -Xmx373m -Xmn140m -XX:PermSize=5m -XX:MaxPermSize=5m

四、延遲調(diào)優(yōu)

在確定了應(yīng)用程序的活躍數(shù)據(jù)大小之后,我們需要再進(jìn)行延遲性調(diào)優(yōu),因為對于此時堆內(nèi)存大小,延遲性需求無法達(dá)到應(yīng)用的需要,需要基于應(yīng)用的情況來進(jìn)行調(diào)試。

在這一步進(jìn)行期間,我們可能會再次優(yōu)化堆大小的配置,評估GC的持續(xù)時間和頻率、以及是否需要切換到不同的垃圾收集器上。

1、系統(tǒng)延遲需求

在調(diào)優(yōu)之前,我們需要知道系統(tǒng)的延遲需求是那些,以及對應(yīng)的延遲可調(diào)優(yōu)指標(biāo)是那些。

應(yīng)用程序可接受的平均停滯時間: 此時間與測量的Minor GC持續(xù)時間進(jìn)行比較。

可接受的Minor GC頻率:Minor GC的頻率與可容忍的值進(jìn)行比較。

可接受的***停頓時間: ***停頓時間與最差情況下FullGC的持續(xù)時間進(jìn)行比較。

可接受的***停頓發(fā)生的頻率:基本就是FullGC的頻率。

以上中,平均停滯時間和***停頓時間,對用戶體驗最為重要,可以多關(guān)注。

基于以上的要求,我們需要統(tǒng)計以下數(shù)據(jù):

MinorGC的持續(xù)時間;

統(tǒng)計MinorGC的次數(shù);

FullGC的最差持續(xù)時間;

最差情況下,F(xiàn)ullGC的頻率;

2、優(yōu)化新生代的大小

 

比如如上的gc日志中,我們可以看到Minor GC的平均持續(xù)時間=0.069秒,MinorGC 的頻率為0.389秒一次。

如果,我們系統(tǒng)的設(shè)置的平均停滯時間為50ms,當(dāng)前的69ms明顯是太長了,就需要調(diào)整。

我們知道新生代空間越大,Minor GC的GC時間越長,頻率越低。

如果想減少其持續(xù)時長,就需要減少其空間大小。

如果想減小其頻率,就需要加大其空間大小。

為了降低改變新生代的大小對其他區(qū)域的最小影響。在改變新生代空間大小的時候,盡量保持老年代空間的大小。

比如此次減少了新生代空間10%的大小,應(yīng)該保持老年代和持代的大小不變化,***步調(diào)優(yōu)后的參數(shù)如下變化:

java -Xms359m -Xmx359m -Xmn126m -XX:PermSize=5m -XX:MaxPermSize=5m新生代的大小有140m變?yōu)?26,堆大小順應(yīng)變化,此時老年代是沒有變化的。

3、優(yōu)化老年代的大小

同上一步一樣,在優(yōu)化之前,也需要采集gc日志的數(shù)據(jù)。此次我們關(guān)注的是FullGC的持續(xù)時間和頻率。

 

上圖中,我們可以看到

FullGC 平均頻率 =5.8sFullGC 平均持續(xù)時間=0.14s(以上為了測試,真實項目的fullGC 沒有這么快)

如果沒有FullGC的日志,有辦法可以評估么?

我們可以通過對象提升率進(jìn)行計算。

對象提升率

比如上述中啟動參數(shù)中,我們的老年代大小=233Mb。

那么需要多久才能填滿老年代中這233Mb的空閑空間取決于新生代到老年代的提升率。

每次提升老年代占用量=每次MinorGC 之后 java堆占用情況 減去 MinorGC后新生代的空間占用

對象提升率=平均值(每次提升老年代占用量) 除以 老年代空間

有了對象提升率,我們就可以算出填充滿老年代空間需要多少次minorGC,大概一次fullGC的時間就可以計算出來了。

比如:

 

上圖中:

***次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ù)期最差頻率時長可以通過以上兩種方式估算出來,可以調(diào)整老年代的大小來調(diào)整FullGC的頻率,當(dāng)然了,如果FullGC持續(xù)時間過長,無法達(dá)到應(yīng)用程序的最差延遲要求,就需要切換垃圾處理器了。具體如何切換,下篇再講,比如切換為CMS,針對CMS的調(diào)優(yōu)方式又有會細(xì)微的差別。

五、吞吐量調(diào)優(yōu)

經(jīng)過上述漫長 調(diào)優(yōu)過程,最終來到了調(diào)優(yōu)的***一步,這一步對上述的結(jié)果進(jìn)行吞吐量測試,并進(jìn)行微調(diào)。

吞吐量調(diào)優(yōu)主要是基于應(yīng)用程序的吞吐量要求而來的,應(yīng)用程序應(yīng)該有一個綜合的吞吐指標(biāo),這個指標(biāo)基于真?zhèn)€應(yīng)用的需求和測試而衍生出來的。當(dāng)有應(yīng)用程序的吞吐量達(dá)到或者超過預(yù)期的吞吐目標(biāo),整個調(diào)優(yōu)過程就可以圓滿結(jié)束了。

如果出現(xiàn)調(diào)優(yōu)后依然無法達(dá)到應(yīng)用程序的吞吐目標(biāo),需要重新回顧吞吐要求,評估當(dāng)前吞吐量和目標(biāo)差距是否巨大,如果在20%左右,可以修改參數(shù),加大內(nèi)存,再次從頭調(diào)試,如果巨大就需要從整個應(yīng)用層面來考慮,設(shè)計以及目標(biāo)是否一致了,重新評估吞吐目標(biāo)。

對于垃圾收集器來說,提升吞吐量的性能調(diào)優(yōu)的目標(biāo)就是就是盡可能避免或者很少發(fā)生FullGC 或者Stop-The-World壓縮式垃圾收集(CMS),因為這兩種方式都會造成應(yīng)用程序吞吐降低。盡量在MinorGC 階段回收更多的對象,避免對象提升過快到老年代。

六、***

據(jù)Plumbr公司對特定垃圾收集器使用情況進(jìn)行了一次調(diào)查研究,研究數(shù)據(jù)使用了84936個案例。在明確指定垃圾收集器的13%的案例中,并發(fā)收集器(CMS)使用次數(shù)最多;但大多數(shù)案例沒有選擇***垃圾收集器。這個比例占用在87%左右。

 

JVM調(diào)優(yōu)是一個系統(tǒng)而又復(fù)雜的工作,目前jvm下的自動調(diào)整已經(jīng)做的比較優(yōu)秀,基本的一些初始參數(shù)都可以保證一般的應(yīng)用跑的比較穩(wěn)定了,對部分團(tuán)隊來說,程序性能可能優(yōu)先級不高,默認(rèn)垃圾收集器已經(jīng)夠用了。調(diào)優(yōu)要基于自己的情況而來。

作者:wier_ali

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2017-07-21 08:55:13

TomcatJVM容器

2024-12-04 15:49:29

2023-04-24 14:54:09

JVM性能調(diào)優(yōu)

2012-01-10 14:35:08

JavaJVM

2021-12-06 11:03:57

JVM性能調(diào)優(yōu)

2020-11-09 07:34:49

JVM性能監(jiān)控

2019-11-01 08:49:07

JVM監(jiān)控性能

2023-11-11 19:07:23

JVMJava

2010-09-27 10:20:09

JVMLinux

2010-09-27 09:23:42

JVM調(diào)優(yōu)

2023-11-10 11:23:20

JVM內(nèi)存

2011-03-10 14:40:54

LAMPMysql

2012-01-10 15:13:56

JavaJVM

2010-09-26 13:39:46

JVM調(diào)優(yōu)

2010-09-26 09:08:17

JVM調(diào)優(yōu)

2010-09-25 15:52:27

JVM內(nèi)存JVM

2012-06-20 11:05:47

性能調(diào)優(yōu)攻略

2019-12-20 14:21:26

JVM調(diào)優(yōu)垃圾回收

2023-12-12 08:00:39

2021-03-04 08:39:21

SparkRDD調(diào)優(yōu)
點贊
收藏

51CTO技術(shù)棧公眾號