日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Jmeter性能测试-GC相关

發布時間:2025/3/20 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Jmeter性能测试-GC相关 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

https://www.cnblogs.com/danqiu/p/6009016.html

?

Jmeter性能測試-GC相關

1.GC相關

HotSpot虛擬機將其物理上劃分為兩個–新生代(young generation)和老年代(old generation)。
新生代(Young generation):?絕大多數最新被創建的對象會被分配到這里,由于大部分對象在創建后會很快變得不可到達,所以很多對象被創建在新生代,然后消失。對象從這個區域消失的過程我們稱之為”minor GC“。

老年代(Old generation):?對象沒有變得不可達,并且從新生代中存活下來,會被拷貝到這里。其所占用的空間要比新生代多。也正由于其相對較大的空間,發生在老年代上的GC要比新生代少得多。對象從老年代中消失的過程,我們稱之為”major GC“(或者”full GC“)

圖中的持久代(?permanent generation?)也被稱為方法區method area)。他用來保存類常量以及字符串常量。因此,這個區域不是用來永久的存儲那些從老年代存活下來的對象。這個區域也可能發生GC。并且發生在這個區域上的GC事件也會被算為major GC。

新生代是用來保存那些第一次被創建的對象,他可以被分為三個空間

  • ?一個伊甸園空間(Eden?
  • ?兩個幸存者空間(Survivor?)
  • 絕大多數剛剛被創建的對象會存放在伊甸園空間。
  • 在伊甸園空間執行了第一次GC之后,存活的對象被移動到其中一個幸存者空間。
  • ? 此后,在伊甸園空間執行GC之后,存活的對象會被堆積在同一個幸存者空間。
  • ?當一個幸存者空間飽和,還在存活的對象會被移動到另一個幸存者空間。之后會清空已經飽和的那個幸存者空間。
  • 在以上的步驟中重復幾次依然存活的對象,就會被移動到老年代。

jstat 是HotSpot JVM提供的一個監控工具

jstat –gc? $<pid$> 1000

?

S0C?????? S1C?????? S0U??? S1U????? EC???????? EU????????? OC???????? OU???????? PC???????? PU???????? YGC???? YGCT??? FGC????? FGCT???? GCT

3008.0?? 3072.0??? 0.0???? 1511.1?? 343360.0?? 46383.0???? 699072.0?? 283690.2?? 75392.0??? 41064.3??? 2540??? 18.454??? 4????? 1.133??? 19.588

3008.0?? 3072.0??? 0.0???? 1511.1?? 343360.0?? 47530.9???? 699072.0?? 283690.2?? 75392.0??? 41064.3??? 2540??? 18.454??? 4????? 1.133??? 19.588

3008.0?? 3072.0??? 0.0???? 1511.1?? 343360.0?? 47793.0???? 699072.0?? 283690.2?? 75392.0??? 41064.3??? 2540??? 18.454??? 4????? 1.133??? 19.588

?

這些信息很重要,因為它們展示了GC處理到底花費了多少時間。

在這個例子中,YGC 是217而YGCT 是0.928,這樣在簡單的計算數據平均數后,你可以知道每次新生代的GC大概需要4ms(0.004秒),而full GC的平均時間為33ms。

但是,只看數據平均數經常無法分析出真正的GC問題。這是主要是因為GC操作時間嚴重的偏差(換句話說,假如兩次full GC的時間是 67ms,那么其中的一次full GC可能執行了10ms而另一個可能執行了57ms。)為了更好地檢測每次GC處理時間,最好使用 –verbosegc來替代數據平均數。

為什么需要優化GC

或者說的更確切一些,對于基于Java的服務,是否有必要優化GC應該說,對于所有的基于Java的服務,并不總是需要進行GC優化,但前提是所運行的基于Java的系統,包含了如下參數或行為:

  • 已經通過?-Xms?和–Xmx 設置了內存大小
  • 包含了?-server?參數
  • 系統中沒有超時日志等錯誤日志

換句話說,如果你沒有設定內存的大小,并且系統充斥著大量的超時日志時,你就需要在你的系統中進行GC優化了。

但是,你需要時刻銘記一條GC優化永遠是最后一項任務。

我為GC優化歸納了兩個目的:

  • 一個是將轉移到老年代的對象數量降到最少
  • 另一個是減少Full GC的執行時間
  • ?

    將轉移到老年代的對象數量降到最少

    按代的GC機制由Oracle JVM提供,不包括可以在JDK7以及更高版本中使用的G1 GC。換句話說,對象被創建在伊甸園空間,而后轉化到幸存者空間,最終剩余的對象被送到老年代。某些比較大的對象會在被創建在伊甸園空間后,直接轉移到老 年代空間。老年代空間上的GC處理會新生代花費更多的時間。因此,減少被移到老年代對象的數據可以顯著地減少Full GC的頻率。減少被移到老年代空間的對象的數量,可能被誤解為將對象留在新生代。但是,這是不可能的。取而代之,你可以調整新生代空間的大小。

    減少Full GC執行時間

    Full GC的執行時間比Minor GC要長很多。因此,如果Full GC花費了太多的時間(超過1秒),一些連接的部分可能會發生超時錯誤。

    • 如果你試圖通過消減老年代空間來減少Full GC的執行時間,可能會導致OutOfMemoryError?或者 Full GC執行的次數會增加。
    • 與之相反,如果你試圖通過增加老年代空間來減少Full GC執行次數,執行時間會增加。

    因此,你需要將老年代空間設定為一個“合適”的值。

    影響GC性能的參數

    正如我們在第二篇文章結尾提到的,不要幻想“某個人設定了GC參數后性能得到極大的提高,我們為什么不和他用一樣的參數?”,因為不同的Web服務所創建對象的大小和他們的生命周期都不盡相同。

    簡單來說,如果一個任務的執行條件是A,B,C,D和E,同樣的任務執行條件換為A和B,你會覺得哪個更快?從一般人的直覺來看,在A和B條件下執行的任務會更快。

    Java GC參數也是相同的道理,設定一些參數不但沒有提高GC執行速度,反而可能導致他更慢。GC優化的最基本原則是將不同的GC參數用于2臺或者多臺服務器,并進行對比,并將那些被證明提高了性能或者減少了GC執行時間的參數應用于服務器。請謹記這一點。

    下面這個表格列出了GC參數中與內存大小相關的,可以影響性能的參數。

    1GC優化需要考慮的Java參數

    定義

    參數

    描述

    堆內存空間

    -Xms

    Heap area size when starting JVM

    啟動JVM時的堆內存空間。

    ?

    -Xmx

    Maximum heap area size

    堆內存最大限制

    新生代空間

    -XX:NewRatio

    Ratio of New area and Old area

    新生代和老年代的占比

    ?

    -XX:NewSize

    New area size

    新生代空間

    ?

    -XX:SurvivorRatio

    Ratio ofEdenarea and Survivor area

    伊甸園空間和幸存者空間的占比

    我在進行GC優化時經常使用-Xms,-Xmx和-XX:NewRatio。-Xms和-Xmx是必須的。你如何設定NewRatio?會對GC性能產生十分顯著的影響。有些人可能會問如何設定Perm區域的大小?你可以通過-XX:PermSize?和-XX:MaxPermSize參數來設定,

    當OutOfMemoryError?錯誤發生并且是由于Perm空間不足導致時,另一個可能影響GC性能的參數是GC類型。下表列出了所有可選的GC類型(基于JDK6.0)

    在分析監控結果后,決定是否進行GC優化

    在檢查GC狀態的過程中,你應該分析監控結果以便決定是否進行GC優化,如果分析結果表明執行GC的時間只有0.1-0.3秒,那你就沒必要浪費時間去進行GC優化。但是,如果GC的執行時間是1-3秒,或者超過10秒,GC將勢在必行。

    但是,如果你已經為Java分配了10GB的內存,并且不能再減少內存大小,你將無法再對GC進行優化。在進行GC優化 之前,你必須想清楚你為什么要分配如此大的內存空間。假如當你分1 GB 或 2 GB內存時出現OutOfMemoryError?,你應該執行堆內存轉儲(heap dump),并消除隱患。

    注意:

    堆內存轉儲是一個用來檢查Java內存中的對象和數據的文件。該文件可以通過執行JDK中的jmap命令來創建。在創建文件的過程中,Java程序會暫停,因此不要再系統執行過程中創建該文件。

    如果GC執行時間滿足下面所有的條件,就意味著無需進行GC優化了。

    • Minor GC執行的很快(小于50ms)
    • Minor GC執行的并不頻繁(大概10秒一次)
    • Full GC執行的很快(小于1s)
    • Full GC執行的并不頻繁(10分鐘一次)

    上面提到的數字并不是絕對的;他們根據服務狀態的不同而有所區別,某些服務可能滿足于Full GC每次0.9秒的速度,但另一些可能不是。因此,針對不同的服務設定不同的值以決定是否進行GC優化。

    • 設定內存空間大小

    下表展示了內存空間大小,GC執行次數以及GC執行時間三者間的關系。

      • 大內存空間
        • 減小GC執行次數
        • 增加GC執行時間
      • 小內存空間
        • 減小GC執行時間
        • 增加GC執行次數

    關于如何設置內存空間的大小,沒有唯一的標準答案。如果服務 器資源足夠,而且Full GC也可能在1秒內完成,設置為10GB當然可行。。但絕大多數服務器并不是這樣,當內存設為10GB時,可能要花費10~30秒來執行Full GC。當然,執行時間會隨對象的大小而改變。

    鑒于如此,我們應該如何設定內存空間大小呢?一 般來說,我建議為500MB。不過請注意這不是讓你將WAS的內存參數設置為–Xms500m?和–Xmx500m。根據優化GC之前的狀態,如果 Full GC執行之后內存空間剩余300MB,那么最好將內存設置為1GB(300MB(默認程序占用)+ 500MB(老年代最小空間)+200MB(空閑內存))。也就是說你要為老年代額外設置500MB。因此,如果你有三個執行服務器,內存分別設置為 1GB,1.5GB,2GB,并且檢查結果。

    理論上來講,GC執行速度應該遵循1GB> 1.5GB> 2GB,因此1GB執行GC速度最快。但是并不說明1GB空間的Full GC會花費1秒而2GB空間會花費2秒。時間取決于服務器的性能和對象的大小。因此,最佳的方式是建立盡可能多的衡量指標來監控他們。

    對于內存空間大小,你應該額外設定NewRatio參數。 NewRatio參數是新生代和老年代空間的比例,即XX:NewRatio=1意味著新生代與老年代之比為1:1。對于1GB來說就是新生代和老年代各 500MB。如果NewRatio為2,意味著新生代老年代之比為1:2,因此該值越大,老年代空間越大,新生代空間越小。

    這看似一件不是很重要的事情,但NewRatio參數會顯著地影響整個GC的性能。如果新生代空間很小,會用更多的對象被轉移到老年代空間,這樣導致頻繁的Full GC,增加暫停時間。

    你可以簡單的認為NewRatio 為1是最佳的選擇,但是,有時可能設置為2或3更好,我就見過很多這樣的例子。

    如何最快的完成GC優化?對比性能測試的結果 應該是最快地方法,為每一臺服務器設置不同的參數并監控他們的狀態,強烈建議至少監控1或2天的數據。但是,當你對GC優化是,你要確保每次執行相同的負 載。并且請求的比率,例如URL都應該是一致的。不過,即便對于專業測試人員要想精確的控制負載也是很難的,并要花費大量的時間準備。因此,相對來說比較 方便和容易的方法是調整才參數,之后花費較長的時間收集結果。?

    示例1

    下面這個例子針對?Service S的優化,對于最近被部署的?Service S,Full GC花費了太長的時間。

    請看?jstat –gcutil的執行結果。

    ?

    1

    2

    S0 S1 E O P YGC YGCT FGC FGCT GCT

    12.16?0.00?5.18?63.78?20.32?54?2.047?5?6.946?8.993

    ?

    最左邊的Perm?空間對于最初的GC優化不是很重要,這一次YGC參數的值更加有用。

    Minor GC和Full GC的平均值如下表所示

    3Service SMinor GC?Full GC的平均執行時間

    GC 類型

    GC 執行次數

    GC 執行時間

    平均

    Minor GC

    54

    2.047

    37 ms

    Full GC

    5

    6.946

    1,389 s

    最重要的是下面兩個數據

    • 新生代實際使用空間: 212,992 KB
    • 老年代實際使用空間: 1,884,160 KB

    因此,總的內存空間為2GB,不算Perm空間的話,新生代與老年代之比為1:9。通過jstat和-verbosegc?日志進行數據收集,并把三臺服務器按照如下方式設置。

    • NewRatio=2
    • NewRatio=3
    • NewRatio=4

    一天之后,檢查系統的GC日志后發現,在設置了NewRatio參數后很幸運的沒有發生Full GC,

    為什么?

    • NewRatio=2: 45 ms
    • NewRatio=3: 34 ms
    • NewRatio=4: 30 ms

    我們看到NewRatio=4 是最佳的參數,雖然它的新生代空間最小,但GC時間確最短。設定這個參數之后,系統沒有執行過Full GC。

    為了說明這個問題,下面是服務之星一段時間后執行jstat –gcutil的結果

    ?

    1

    2

    S0 S1 E O P YGC YGCT FGC FGCT GCT

    8.61?0.00?30.67?24.62?22.38?2424?30.219?0?0.000?30.219

    ?

    你可能會認為因為服務器接受的請求少才導致的GC執行頻率下降。實際上,雖然Full GC沒有執行,但是Minor GC被執行了 2,424次。

    示例2

    這是一個針對ServiceA的例子,我們通過公司內部的應用性能管理系統(APM)發現JVM暫停了相當長的時間(超過8秒),因此我們進行了GC優化。我們找到了Full GC執行時間過長的原因,并著手解決。

    進行GC優化的第一步,就是我們添加了-verbosegc參數,并得到如下結果。

    1:進行GC優化之前的STW時間

    如上圖所示,由HPJMeter自動生成的圖片之一。X坐標表示JVM執行的時間。Y坐標表示每次GC的時間。CMS綠點,表示Full GC結果。Parallel Scavenge藍點,表示Minor GC結果。

    之前我曾經說過CMS GC是最快的,但是上面的的結果顯示出于某種原因,它最多花費了15秒。是什么導致這個結果?是否想起我之前提過的,CMS在進行內存清理時,會變慢。與此同時,服務的內存被設定為?–Xms1g和–Xmx4g?,且實際分配了4GB內存。

    因此,我將GC類型從CMS改為Parallel GC。并且將內存改為2GB,設定NewRatio?為3。幾小時之后我使用?jstat –gcutil得到如下結果

    ?

    1

    2

    S0 S1 E O P YGC YGCT FGC FGCT GCT

    0.00?30.48?3.31?26.54?37.01?226?11.131?4?11.758?22.890

    ?

    相對于4GB時的15秒,Full GC變成了平均每次3秒。但是3秒一樣比較慢,因此我設計了如下6種場景。

    • Case 1:?-XX:+UseParallelGC -Xms1536m -Xmx1536m -XX:NewRatio=2
    • Case 2:?-XX:+UseParallelGC -Xms1536m -Xmx1536m -XX:NewRatio=3
    • Case 3:?-XX:+UseParallelGC -Xms1g -Xmx1g -XX:NewRatio=3
    • Case 4:?-XX:+UseParallelOldGC -Xms1536m -Xmx1536m -XX:NewRatio=2
    • Case 5:?-XX:+UseParallelOldGC -Xms1536m -Xmx1536m -XX:NewRatio=3
    • Case 6:?-XX:+UseParallelOldGC -Xms1g -Xmx1g -XX:NewRatio=3

    那一個最快呢?結果顯示,內存越小,結果越好。下圖展示了Case6的結果。這是GC的性能最好。最長的響應時間只有1.7秒。平均時間在1秒之內。

    2Case6的時間圖表

    基于以上結果。我們按照Case6調整了GC參數。但是,這導致了每天晚上都會發生OutOfMemoryError。在這里很難解釋具體的原因。簡單來說,批處理程序導致了內存泄漏。相關的問題已經被解決。

    如果對GC日志只分析很短的時間就貿然對所有服務器進行優化是非常危險的。請時刻牢記,你必須同時分析GC日志和應用程序。

    我們回顧了兩個關于GC優化的例子,正如我之前提到的,例子中提到的GC參數,可以設置在相同的服務器之上,但前提是他們具有相同的CPU,操作系統,JDK版本以及運行著相同的服務。但是不要直接把我用過的參數用到你的服務至上,它們未必能很好的工作。

    ?

    切實地調優

    如果測試的結果滿足了預期,那么你不需要對程序進行性能調優。如果沒有達到預期結果,你就應該執行調優來解決問題。接下來會通過實例講解方法。

    stop-the-world耗時過長

    stop-the-world耗時過長可能是由于GC參數不合理或者代碼實現不正確。你可以通過分析工具或堆內存轉儲文件(Heap dump)來定位問題,比如檢查堆內存中對象的類型和數量。如果在其中找到了很多不必要的對象,那么最好去改進代碼。如果沒有發現創建對象的過程中有特別 的問題,那么最好單純地修改GC參數。

    為了適當地調整GC參數,你需要獲取一段足夠長時間的GC日志,還必須知道哪些情況會導致長時間的stop-the-world。想了解更多關于如何選擇合適的GC參數,可以閱讀我同事的一篇博文:How to Monitor Java Garbage Collection。

    CPU使用率過低

    當系統發生阻塞,吞吐量和CPU使用率都會降低。這可能是由于網絡系統或者并發的問題。為了解決這個問題,你可以分析線程轉儲信息(Thread dump)或者使用分析工具。閱讀這篇文章可以獲得更多關于線程轉儲分析的知識:How to Analyze Java Thread Dumps。

    你可以使用商業的分析工具對線程鎖進行精確的分析,不過大部分時候,只需使用JVisualVM中的CPU分析器,就能獲得足夠的信息。

    CPU使用率過高

    如果吞吐量很低但是CPU使用率卻很高,很可能是低效率代碼導致的。這種情況下,你應該使用分析工具定位代碼中性能的瓶頸。可使用的工具有:JVisualVM、Eclipse?TPTP或者JProbe

    調優方法

    建議你使用如下方法對程序進行調優。

    首先,檢查性能調優是否必要。測量性能不是一件簡單的工作,你也不能保證每次都獲得滿意的結果。因此如果程序已經滿足預期性能需求,不必在調優上增加額外的投入了。

    問題只出在一個地方,你要做的就是去解決掉它。二八定律(Pareto principle)對性能調優同樣適用。這不是說某個模塊的低性能一定只源于一個問題,而是強調我們應該在調優時把注意力放在影響最大的那個問題上。在處理好了最重要的之后,你才應該去解決剩下其他的。也就是建議一次只對一個問題進行修復。

    另外需要考慮到氣球效應(Balloon effect),有得必有失。你可以通過使用緩存來提高響應能力,但是當緩存逐漸增大,執行一次Full GC的時間也會更長。一般而言,如果你希望內存使用率比較低,那么吞吐量和響應能力可能都會惡化。因此,要知道什么對自己程序來說最重要的,而哪些又是次要的。

    到此為止,你應該已經了解了如何對Java程序進行性能調優。為了介紹性能測定的具體過程,我不得不省略其中一些細節,不過我認為這些也足夠應對大多數Java Web服務端程序了

    ?

    2.操作相關

    1.如何考慮一個性能需求

    1.?通常拿到一個性能需求,需要了解接口模型,整個接口的使用比例和容量,系統結構和技術方案,數據庫緩存和索引分布,設計出合理的測試計劃,設計的原則是盡可能真實的模擬線上情況。

    2.根據設計出的測試計劃,使用一個線程運行測試計劃,得出測試結果,對比測試指標

    3.以線性增長的方式增加并發數,比較測試結果是否為線性增長

    4.測試結果平緩區通常代表著系統容量的最大區域,分析此時的測試結果,如 TPS和響應時間等

    5.分析數據庫TPS、QPS等數據,redis命中率,MQ吞吐率,javaGC,程序占用時間等各方面因素提高系統性能

    6.通過jstack分析各模塊的資源占用情況。

    7.優化后的程序要經過大批量數據測試確保測試程序不會發生錯誤

    8.根據測試概要報告,數據庫監控數據等數據整合測試報告

    9. 需要關注api層用的是長連接還是短連接,長連接的話需要在jmeter里勾選keep alive

    2.如何保證jmeter自身性能

    1.使用命令行啟動,減少界面造成的性能問題

    2.命令行記錄聚合報告,不要啟動過多的其他監控報告

    3.盡可能關閉不必要的日志,包括測試代碼的log,jmeter自身日志。

    4.確保測試腳本計時準確,需確認好那些步驟需要計時,那些在準備在計時之外

    5.過多的并發使用分布式請求,當本地cpu,mem占用比較大時,修改jmeter.properties,增加遠程remote-server,并啟動(具體操作見jmeter操作手冊)

    3.如何分析測試結果

    1.根據聚合報告分析90%,95%,和最大等指標,找出程序普遍的響應時間。

    2.讓開發人員查詢最大響應時間時的日志,分析程序層面的執行任務情況

    3.使用jstack等分析當前程序的資源等待情況,系統資源情況

    值得關注的線程狀態有:
    ?????死鎖,Deadlock(重點關注)
    ?????執行中,Runnable??
    ?????等待資源,Waiting on condition(重點關注)
    ?????等待獲取監視器,Waiting on monitor entry(重點關注)
    ?????暫停,Suspended
    ?????對象等待中,Object.wait() 或 TIMED_WAITING
    ?????阻塞,Blocked(重點關注)?
    ?????停止,Parked

    示例圖

    4.分析gc結果,cpu,IO等情況,分析程序是否充分利用了系統資源

    5.對比分析各并發數的程序響應情況。

    分類:?性能測試

    轉載于:https://my.oschina.net/u/3160044/blog/2966729

    總結

    以上是生活随笔為你收集整理的Jmeter性能测试-GC相关的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。