壓測時頻繁full-gc問題排查


jmeter壓測

配置線程組
image

配置壓測接口
image

執行壓測后 可以發現后台一直在報OOM
image

arthas排查

# 安裝 arthas
sudo curl -O https://arthas.aliyun.com/arthas-boot.jar

# 執行
java -jar arthas-boot.jar

image
選擇對應的Java線程

Current VM java version: 11 do not match target VM java version: 1.8, attach may fail.

提示錯誤 啟動服務時選擇JDK11

列出1000ms內最忙的3個線程棧 發現GC線程一直在運行

[arthas@38198]$ thread -n 3 -i 1000
"GC Thread#3" [Internal] cpuUsage=47.06% deltaTime=473ms time=5430ms


"GC Thread#6" [Internal] cpuUsage=46.34% deltaTime=465ms time=5383ms


"GC Thread#4" [Internal] cpuUsage=45.71% deltaTime=459ms time=5358ms

dump live對象到指定文件

heapdump --live /tmp/dump.hprof

MAT分析工具

打開提示:The JVM shared library "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/../lib/server/libjvm.dylib" does not contain the JNI_CreateJavaVM symbol.

image

在應用列表,找到MAT.app,然后右鍵單擊后,選擇“顯示包內容” 進入Contents目錄 ,修改Info.plist文件

注意:新版本的MAT(1.12版本)必須配置Oracle JDK11。使用zulu jdk也會報錯

image

配置完重新打開MAT 選擇 File - OPEN DUMP 文件
image

可以看到每個請求占用了4M的內存,由於當前服務設置了內存大小512M。 當請求並發數上來后必定發生GC
image

問題排查

看OOM日志可以發現都是tomcat相關的代碼在報錯,大概率是相關配置出現問題。查看服務相關配置 發現設置了

server:
  max-http-header-size: 4194304

該參數用來設置http請求頭的大小,默認值為8k,也就是8 * 1024的大小。
那么,什么時候會配置max-http-header-size參數呢?

比如,當我們上傳圖片時采用multipart形式上傳文件時,對應的配置如下

spring.http.multipart.max-file-size=20Mb  
spring.http.multipart.max-request-size=60Mb 

但這個配置針對base64形式上傳圖片就不適用了,需要如下配置:

server.maxHttpHeaderSize=102400
server.maxHttpPostSize =102400

但這樣的配置就很容易造成OOM。
之所以該參數配置過大,在並發的時候會造成OOM是因為Http請求時內存分配的問題。

比如將max-http-header-size的大小配置為4M,那么並發量100時,那么內存分配就是4 * 100,將近400M。

翻看源碼會發現,該參數會被用於ByteBuffer.allocate的調用,ByteBuffer.allocate就是生成一個指定長度的字節數組,也就是說這個bufLength有多大,這個字節數組就有多長,而bufLength又是headerBufferSize加上了某個值。如果headerBufferSize=102400,那么這個地方就會生成一個至少102400長度的字節數組,這非常消耗內存。

同時大對象會被直接放入老年代,引發full GC等。

所以當並發量比較大時,會迅速消耗掉內存,甚至造成OOM。

重新壓測

修改配置max-http-header-size: 8096重新壓測 使用jvisualvm 報錯

The operation couldn’t be completed. Unable to locate a Java Runtime that supports jvisualvm.
Please visit http://www.java.com for information on installing Java.

下載單獨的jvisualvm 軟件:
https://visualvm.github.io/download.html
image

安裝GC插件

離線安裝

https://visualvm.github.io/pluginscenters.html
image
進入頁面選擇對應插件下載

在線安裝

image

查看GC情況 發現現在並發100可以平穩運行


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM