1. 程式人生 > >性能測試三十六:內存溢出和jvm常見參數

性能測試三十六:內存溢出和jvm常見參數

空間 0ms 成功 mar 大量 ali mem .com 分享

堆內存溢出:

此種溢出,加內存只能緩解問題,不能根除問題,需優化代碼
堆內存中存在大量對象,這些對象都有被引用,當所有對象占用空間達到堆內存的最大值,就會出現內存溢出OutOfMemory:Java heap space


永久代溢出

如果發生,則是在初始化的時候,空間太小,解決辦法,擴大空間
類的一些信息,如類名、訪問修飾符、字段描述、方法描述等,所占空間大於永久代最大值,就會出現OutOfMemoryError:PermGen space

內存溢出的檢測方法:pid=1730

技術分享圖片

Jdk/bin目錄下有很多檢測工具
圖形界面:
  Jconsole
  Jvisualvm
命令行工具:

  Jstat –gcutil pid 1000 100 (只需要看O,如果達到100%,並且長期處於100%,則代表老年代內存不足)

    pid:進程號、1000:1秒鐘獲取一次、100一共獲取100次

    E:eden區
    O:老年代
    P:永久代
    YGC:新生代的GC次數
    YGCT:當前統計的YGC一共花費的時間(毫秒)
    FGC:fullGC老年代的GC次數
    FGCT:當前統計的FGC一共花費的時間(毫秒)
    GCT:YGC+FGC

技術分享圖片

  

  Jmap –histo pid | head -20
  把當前JVM裏面的所有對象打印出來,排序,head:頭部,head -20 前20行

技術分享圖片

  Jmap –heap pid(列出當前進程的堆的數據,一般用來看當前配置)

技術分享圖片

技術分享圖片

在jvisualvm上面也可以看到JVM參數

技術分享圖片

技術分享圖片

FullGC頻率:單次FullGC時間<200ms

Jvm常見參數
-Xms2048m,初始堆大小,建議<物理內存的1/4,默認值為物理內存的1/64
-Xmx2048m,最大堆大小,建議與-Xms保持一致,默認值為物理內存的1/4
-Xmn512m,新生代大小,建議不超過堆內存的1/2
-Xss256k,線程年輕代堆棧大小,建議256k
-XX:PermSize=256m,永久代初始值,默認值為物理內存的1/64
-XX:MaxPermSize=256m,永久代最大值,默認值為物理內存的1/4
-XX:SurvivorRatio=8:年輕帶中Eden區和Survivor區的比例,默認為8:1:1,即Eden(8),From Space(1),ToSpace(1)
-XX:+UseConcMarkSweepGC:開啟CMS垃圾回收器

看一下內存溢出的情況

先配置一下tomcat裏面JVM的參數:vi /home/server/tomcat-PerfTeach01/bin/catalina.sh

技術分享圖片

技術分享圖片

由於ip變了,改一下host裏面的ip

技術分享圖片

技術分享圖片

啟動tomcat

技術分享圖片

能訪問,代表啟動成功:http://localhost:8080/PerfTeach/MemoryLeak?userId=123&password=abc&waitTime=3

技術分享圖片

jmeter5個並發永遠跑

技術分享圖片

TPS

技術分享圖片

響應時間

技術分享圖片

cpu

技術分享圖片

jstat -gcutil 1730 1000 1000

技術分享圖片

jvisualvm

技術分享圖片

看一下tomcat日誌的後200行

技術分享圖片

有內存溢出的報錯

技術分享圖片

看當前JVM裏面的所有對象,找com開頭的,業務代碼,再找非java開頭的

可以看出org.apache可能有問題,com.lee是業務代碼,一定有問題

直接告訴開發,讓開發去解決技術分享圖片

jvisualvm也可以生成快照,一開始出現內存泄漏的時候就點堆Dump在服務器下生成快照,下載後再用 jvisualvm打開, jvisualvm_文件_裝入_文件類型選“線程 Dump”

技術分享圖片

技術分享圖片

內存泄漏的本質:老年代空間裏面東西放滿了,又不能被回收

程序一旦出現內存泄漏,就算停止壓測也不能解決,只能重啟

內存泄露會出現的現象
1,tps出現大幅波動,並慢慢降低,甚至降為0,響應時間隨之波動,慢慢升高
2,通過jstat命令看到,Jvm中Old區不斷增加,FullGC非常頻繁,對應的FullGC消耗的時間也不斷增加
3,通過jconsole/jvisualvm可以看到,堆內存曲線不斷上升,接近上限時,變成一條直線
4,日誌報錯java.lang.OutOfMemoryError: Java heap space

內存泄露定位
1,通過jmap命令:jmap -histo pid | head -20,查看當前堆內存中實例數和占用內存最多的前20個對象
2,通過jvisualvm,進行遠程堆dump,然後把dump文件下載下來,用jvisualvm打開進行分析,可以看到更直觀的jvm中對象的信息

監控內存泄露問題的場景
1,在試壓階段,或任意場景都可以考慮通過jvisualvm和jstat監控jvm的情況
2,在穩定性場景中,一定要關註Jvm內存使用的情況,在長時間的壓測下,最容易看出內存泄露的問題

性能測試三十六:內存溢出和jvm常見參數