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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

jstat的小伙伴:找出system.gc的调用的小工具

發布時間:2024/1/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jstat的小伙伴:找出system.gc的调用的小工具 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

場景分析

現場環境中,造成gc頻繁的可能性之一就是通過system.gc主動調用了gc。這種情況出現在開發人員業務代碼,或者是jdk自身的代碼中(例如nio)。我們可以通過jstat -gccause查看gc的原因,如果真的是system.gc,那么找出調用的代碼就是繼續解決問題的關鍵。

查看system.gc的調用

如果說查看代碼調用,那么jstack就是首選,仔細想想,代碼的觸發時機不定,怎么才能去在合適的時候打印堆棧呢,最簡單的想法就是定時的去調用,這個方法是有用的,只不過在頻繁調用的時候,是可以捕獲到的??墒侨f一不頻繁調用呢。

當我們想知道自己的代碼在什么時候被調用,那么最好的方式就是在自己的方法里去打印堆棧。這樣就知道是誰調用的了,也不用擔心是調用的時機等等。

解決方案也就出來了,那就是在system.gc調用的時候順便打印一下堆棧。system是jdk的類,可以自己編寫一個system類替換掉jdk的,只不過不想用的時候還得改回來。為了靈活我們選擇動態修改字節碼。

字節碼改造

我們先想想打印堆棧的代碼

StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();for (StackTraceElement element : stackTrace) {System.out.println(element);}

現在呢,我們就在system.gc前調用這個方法。這里修改字節碼的方式,我們使用asm。

InsnList list = new InsnList();list.add(getLabelNode());list.add(new MethodInsnNode(INVOKESTATIC, "com/xp/agent/core/ThreadInfo", "getStack", "()V", false));insns.insert(list);

修改完就大功告成。

細節補充

字節碼是改成了,但是我們的那個類路徑得讓加載system類的classloader(bootstrapclassloader)找到我們的類。否則會拋出classnotfind或者noclassdefineerror。這里我們通過增加配置文件的方式。

Agent-Class: com.xp.agent.main.Main Can-Redefine-Classes: true Can-Retransform-Classes: true Class-Path: trace-0.0.1-SNAPSHOT-common.jar asm-all-6.0_BETA.jar Created-By: Apache Maven 3.3.9 Build-Jdk: 1.8.0_121 Boot-Class-Path: trace-0.0.1-SNAPSHOT-agentcore.jar

代碼地址

大佬如果喜歡,可以點個星鼓勵一下。

https://github.com/xpbob/lightTrace

總結

以上是生活随笔為你收集整理的jstat的小伙伴:找出system.gc的调用的小工具的全部內容,希望文章能夠幫你解決所遇到的問題。

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