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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

又是一个程序员粗心的代码引起频繁FullGC的案例

發布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 又是一个程序员粗心的代码引起频繁FullGC的案例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是笨神JVMPocket群里一位名為”云何*住“的同學提出來的問題,問題現象是CPU飆高并且頻繁FullGC

?

重現問題


這位同學的業務代碼比較復雜,為了簡化業務場景,筆者將其代碼壓縮成如下的代碼片段:

public class FullGCDemo {private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50,new ThreadPoolExecutor.DiscardOldestPolicy());public static void main(String[] args) throws Exception {executor.setMaximumPoolSize(50);// 模擬xxl-job 100ms 調用一次, 原代碼沒有這么頻繁for (int i=0; i<Integer.MAX_VALUE; i++){buildBar();Thread.sleep(100);}}private static void buildBar(){List<FutureContract> futureContractList = getAllFutureContract();futureContractList.forEach(contract -> {// do somethingexecutor.scheduleWithFixedDelay(() -> {try{doFutureContract(contract);}catch (Exception e){e.printStackTrace();}}, 2, 3, TimeUnit.SECONDS);});}private static void doFutureContract(FutureContract contract){// do something with futureContract}private static List<FutureContract> getAllFutureContract(){List<FutureContract> futureContractList = new ArrayList<>();// 問題代碼這里每次只會new不到10個對象, 我這里new了100個是為了更快重現問題for (int i = 0; i < 100; i++) {FutureContract contract = new FutureContract(i, ... ...);futureContractList.add(contract);}return futureContractList;} }

說明,為了更好的還原問題,FutureContract.java?的定義建議盡量與問題代碼保持一致:

  • 16個BigDecimal類型屬性
  • 3個Long類型屬性
  • 3個String類型屬性
  • 4個Integer類型屬性
  • 2個Date類型屬性

問題代碼運行時的JVM參數如下(JDK8):

java -Xmx256m -Xms256m -Xmn64m FullGCDemo

你也可以先自己獨立思考一下這塊代碼問題何在。

?

CPU飆高


這是第一個現象,top命令就能看到,找到我們的進程ID,例如91782。然后執行命令top -H -p 91782查看進程里的線程情況:

PID?USER??????PR??NI??VIRT??RES??SHR?S?%CPU?%MEM????TIME+??COMMAND????????????????????????????????????????????????????? 91784?yyapp?????20???0?2670m?300m??12m?R?92.2??7.8???4:14.39?java????????????????????????????????????????????????????????? 91785?yyapp?????20???0?2670m?300m??12m?R?91.9??7.8???4:14.32?java????????????????????????????????????????????????????????? 91794?yyapp?????20???0?2670m?300m??12m?S??1.0??7.8???0:09.38?java????????????????????????????????????????????????????????? 91799?yyapp?????20???0?2670m?300m??12m?S??1.0??7.8???0:09.39?java

由這段結果可知線程91784和91785很消耗CPU。將91784和91785分別轉為16進制,得到16688和16689。接下來通過執行命令命令jstack -l 91782 > 91782.log導出線程棧信息(命令中是進程ID),并在線程dump文件中尋找16進制數16688和16689,得到如下兩條信息:

"GC?task?thread#0?(ParallelGC)"?os_prio=0?tid=0x00007f700001e000?nid=0x16688?runnable? "GC?task?thread#1?(ParallelGC)"?os_prio=0?tid=0x00007f7000020000?nid=0x16689?runnable

由這兩行結果可知,消耗CPU的是ParallelGC線程。因為問題代碼搭配的JVM參數沒有指定任何垃圾回收器,所以用的是默認的PS垃圾回收,所以這個JVM實例應該在頻繁FullGC,通過命令jstat -gcutil 91782 5s查看GC表現可以驗證,由這段結果可知,Eden和Old都占滿了,且不再發生YGC,但是卻在頻繁FGC,此時的應用已經不能處理任務,相當于假死了,好可怕:

S0?????S1?????E??????O??????M?????CCS????YGC?????YGCT????FGC????FGCT?????GCT?0.00???0.00?100.00??99.98??78.57??83.36??????5????0.633???366??327.647??328.2810.00???0.00?100.00??99.98??78.57??83.36??????5????0.633???371??331.965??332.5980.00???0.00?100.00??99.98??78.57??83.36??????5????0.633???376??336.996??337.6290.00???0.00?100.00??99.98??78.57??83.36??????5????0.633???381??340.795??341.4280.00???0.00?100.00??99.98??78.57??83.36??????5????0.633???387??346.268??346.901

?

揪出真兇


到這里基本可以確認是有對象沒有釋放導致即使發生FullGC也回收不了引起的,準備dump進行分析看看Old區都是些什么妖魔鬼怪,執行命令jmap -dump:format=b,file=91782.bin 91782,用MAT分析時,強烈建議開啟keep unreachable objects:

接下來點擊Actions下的Histogram,查找大對象:

下面貼出的是原圖,而不是筆者的Demo代碼跑出來的:

由這段代碼可知,大量的FutureContract和BigDecimal(說明:因為FutureContract中有多達16個BigDecimal類型的屬性),FutureContract占了120MB,BigDecimal占了95MB。那么就可以斷定問題是與FutureContract相關的代碼造成的,如果是正常的JVM示例,Histogram?試圖最占內存的是byte[]和char[]兩個數組,兩者合計一般會占去80%左右的內存,遠遠超過其他對象占用的內存。

接下來通過FutureContract就找到上面這塊buildBar方法代碼,那么為什么是這塊代碼無法釋放呢?單獨把這塊代碼擰出來看看,這里用到了ScheduledThreadPoolExecutor定時調度,且每3秒執行一次,然而定時器中需要的參數來自外面的List<FutureContract>,這就會導致List<FutureContract>這個對象一直被一個定時任務引用,永遠無法回收,從而導致FutureContract不斷晉升到Old區,直到占滿Old區然后頻繁FullGC。

private static void buildBar(){List<FutureContract> futureContractList = getAllFutureContract();futureContractList.forEach(contract -> {// do somethingexecutor.scheduleWithFixedDelay(() -> {try{doFutureContract(contract);}catch (Exception e){e.printStackTrace();}}, 2, 3, TimeUnit.SECONDS);}); }

那么為什么會出現這種情況呢?我相信一個程序員不應該犯這樣的低級錯誤,后來看到原生代碼,我做出一個比較合理的猜測,其本意可能是想通過調用Executor executor來異步執行,誰知小手一抖,在紅色框那里輸入了taskExecutor,而不是executor:

?

解決問題


OK,知道問題的根因,想解決問題就比較簡單了,將taskExecutor改成executor即可:

private static ThreadPoolExecutor executor = new ThreadPoolExecutor(50, 50, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(128)); private static void buildBar(){List<FutureContract> futureContractList = getAllFutureContract();futureContractList.forEach(contract -> {// do somethingexecutor.execute(() -> {try{doFutureContract(contract);}catch (Exception e){e.printStackTrace();}});}); }

或者將這一塊直接改成同步處理,不需要線程池:

private static void buildBar(){List<FutureContract> futureContractList = getAllFutureContract();futureContractList.forEach(contract -> {// do somethingtry{doFutureContract(contract);}catch (Exception e){e.printStackTrace();}}); }

總結

以上是生活随笔為你收集整理的又是一个程序员粗心的代码引起频繁FullGC的案例的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 欧美激情国产日韩精品一区18 | 久久日视频 | 国产一区二区福利 | 激情高潮呻吟抽搐喷水 | 91激情网| 久久精品综合 | 五月婷婷一区二区 | 99热精品在线 | 97久久超碰 | 无码乱人伦一区二区亚洲 | 国产欧美精品在线 | 亚洲色图制服丝袜 | 在线观看成人动漫 | 免费毛片a| 国产成人一级 | 中文字幕精品一区二区三区精品 | 国产精品毛片va一区二区三区 | 国产黄色免费大片 | 性欧美在线观看 | 久久亚洲私人国产精品va | 天天想你在线观看完整版高清 | 日韩精品视频在线观看免费 | 免费色播| 713电影免费播放国语 | 中文字幕人成 | 国产午夜在线一区二区三区 | 欧美性受xxx黑人xyx性爽 | 国产精品国产三级国产aⅴ9色 | 最新中文字幕 | 亚洲色图狠狠干 | 亚洲久久视频 | 紧身裙女教师三上悠亚红杏 | 四虎av在线播放 | av不卡在线播放 | 九色亚洲 | 91制服诱惑 | 国产粉嫩白浆 | 国产毛片18 | 蜜桃av在线看 | 一区二区三区天堂 | 黄网站在线播放 | 受虐m奴xxx在线观看 | 伊人久久影院 | 免费萌白酱国产一区二区三区 | 中文不卡在线 | 欧美激情精品久久久久久 | 天天草天天草 | 免费看a网站 | 美女一区二区视频 | 国产视频黄 | 久草久草 | 人妻精品久久久久中文字幕 | 成人毛片视频在线观看 | 欧美大胆视频 | av片免费在线 | 日本a级片在线播放 | 2019中文字幕在线视频 | 经典一区二区 | 亚洲播放器 | 四虎最新站名点击进入 | 男女无遮挡做爰猛烈视频 | 成人在线高清视频 | 国产18页| 欧美黄色高清视频 | 国产成人精品影院 | 外国毛片 | 国产精品一区电影 | 精品国产污污免费网站入口 | 欧美日韩在线直播 | 天天骑夜夜操 | 狠狠鲁视频 | 麻豆av电影网 | 欧美高清在线观看 | 波多野结衣视频网站 | 欧美性一级片 | 麻豆精品国产传媒av绿帽社 | 日韩精品乱码久久久久久 | 91久久爱 | 亚洲av无一区二区三区怡春院 | 奇米色在线 | 欧美一区二区三区黄色 | 久久亚洲av午夜福利精品一区 | 亚洲综合在线成人 | 国产成人久久精品 | 亚洲无色 | 三级全黄视频 | 91嫩草影视 | 天堂网一区二区三区 | 91亚洲国产成人精品一区 | gv天堂gv无码男同在线观看 | 黄色一级国产 | 女人被狂躁c到高潮喷水电影 | 芭乐视频色 | 91午夜在线观看 | 国产无遮挡又黄又爽免费视频 | 久久久精品视频网站 | 人体裸体bbbbb欣赏 | 亚洲高清在线观看 | 亚洲色图在线播放 |