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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Java线上程序频繁JVM FGC问题排障与启示

發布時間:2023/11/27 生活经验 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java线上程序频繁JVM FGC问题排障与启示 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線上Java程序的JVM頻繁FGC,現象如圖所示:

一直持續FGC 5次左右,每次耗時1秒多不等。

FGC的原因實際上是內存不夠用,但是運維反映堆內存是2G,從運維提供的參數看也是。

內存實際上一直只用到1G以內。

?

這時候可以自己寫一段代碼輸出堆內存數據,這是最準的:

public class JVMTest {public static void main(String[] args) throws Exception {MemoryMXBean mxb = ManagementFactory.getMemoryMXBean();//HeapSystem.out.println("Max:" + mxb.getHeapMemoryUsage().getMax() / 1024 / 1024 + "MB");    //Max:1776MBSystem.out.println("Init:" + mxb.getHeapMemoryUsage().getInit() / 1024 / 1024 + "MB");  //Init:126MBSystem.out.println("Committed:" + mxb.getHeapMemoryUsage().getCommitted() / 1024 / 1024 + "MB");   //Committed:121MBSystem.out.println("Used:" + mxb.getHeapMemoryUsage().getUsed() / 1024 / 1024 + "MB");  //Used:7MBSystem.out.println(mxb.getHeapMemoryUsage().toString());    //init = 132120576(129024K) used = 8076528(7887K) committed = 126877696(123904K) max = 1862270976(1818624K)//Non heapSystem.out.println("Max:" + mxb.getNonHeapMemoryUsage().getMax() / 1024 / 1024 + "MB");    //Max:0MBSystem.out.println("Init:" + mxb.getNonHeapMemoryUsage().getInit() / 1024 / 1024 + "MB");  //Init:2MBSystem.out.println("Committed:" + mxb.getNonHeapMemoryUsage().getCommitted() / 1024 / 1024 + "MB");   //Committed:8MBSystem.out.println("Used:" + mxb.getNonHeapMemoryUsage().getUsed() / 1024 / 1024 + "MB");  //Used:7MBSystem.out.println(mxb.getNonHeapMemoryUsage().toString());    //init = 2555904(2496K) used = 7802056(7619K) committed = 9109504(8896K) max = -1(-1K)}
}

參考:https://www.cnblogs.com/songxingzhu/p/9106394.html?

?

這是本地的測試數據,很明顯自己設定的內存都生效了,然后拿到線上一跑果然實際堆最大內存是900多M,所以內存觸發了閾值就FGC。所以FGC的根源還是內存不夠,運維設置不對,運維設置了2G,但是實際上由于使用上的問題不生效

所以要用數據說話,不要去猜測,也不要過度相信配置,因為已經FGC了,而且內存上不了1G。

java-Xms64m #JVM啟動時的初始堆大小-Xmx128m #最大堆大小-Xmn64m #年輕代的大小,其余的空間是老年代-XX:MaxMetaspaceSize=128m #-XX:CompressedClassSpaceSize=64m #使用 -XX:CompressedClassSpaceSize 設置為壓縮類空間保留的最大內存。-Xss256k #線程-XX:InitialCodeCacheSize=4m #-XX:ReservedCodeCacheSize=8m # 這是由 JIT(即時)編譯器編譯為本地代碼的本機代碼(如JNI)或 Java 方法的空間-XX:MaxDirectMemorySize=16m-XX:NativeMemoryTracking=summary #開啟內存追蹤-jar app.jar

#java -Xms2048m -Xmx2048m ?-Xmn64m ? -cp Test-1.0.0.jar com.test.JVMTest ?start

這個只是本地模擬,線上參數需要比這個復雜。

?

再回到前面的問題為什么回運維設置不生效呢?

因為這個原因:

Java 8u131及以上版本開始支持了Docker的cpu和memory限制。

cpu limit

即如果沒有顯式指定-XX:ParalllelGCThreads 或者 -XX:CICompilerCount, 那么JVM使用docker的cpu限制。如果docker有指定cpu limit,jvm參數也有指定-XX:ParalllelGCThreads 或者 -XX:CICompilerCount,那么以指定的參數為準。

memory limit

在java8u131+及java9,需要加上-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap才能使得Xmx感知docker的memory limit。

-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap (正確的識別容器限制,910.50M)安全

關于這個解釋可以參考此文即可:http://virtual.51cto.com/art/201901/589723.htm

具體使用不使用這個參數需要結合實際情況。

?

后來據運維說是參數配置問題:

java -server -jar XXX.jar -Xms2048m -Xmx2048m 這是錯的

java -server -jar -Xms2048m -Xmx2048m XXX.jar 要這樣

延申閱讀:記一次頻繁FGC的簡單排查

一次JVM GC長暫停的排查過程

總結

以上是生活随笔為你收集整理的Java线上程序频繁JVM FGC问题排障与启示的全部內容,希望文章能夠幫你解決所遇到的問題。

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