日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Java 虚拟机诊断利器

發布時間:2025/3/20 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 虚拟机诊断利器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者 | 小白一只

【Arthas 官方社區正在舉行征文活動,參加即有獎品拿~點擊投稿】

背景

最近學習Java字節碼過程中遇到了反射,有段代碼是這樣的:

package com.example.classstudy;import java.lang.reflect.Method;/*** @author TY*/ public class ReflectionTest {private static int count = 0;public static void foo() {new Exception("test#" + (count++)).printStackTrace();}public static void main(String[] args) throws Exception {Class<?> clz = Class.forName("com.example.classstudy.ReflectionTest");Method method = clz.getMethod("foo");for (int i = 0; i < 20; i++) {method.invoke(null);}} }

就是一段簡單的反射調用 foo 方法,執行 20 次,然后看執行結果:

可以看到在 15 次調用 foo 方法后,第 16 次調用 foo 方法是走的 GeneratedMethodAccessor1 來調用的。我嘞個擦,怎么回事,調著調著就不一樣了,于是跟代碼,跟到了下面這個類:

其中這句代碼就是對反射調用的次數做了控制

if (++this.numInvocations > ReflectionFactory.inflationThreshold() && !ReflectUtil.isVMAnonymousClass( this.method.getDeclaringClass())) {MethodAccessorImpl var3 = (MethodAccessorImpl)(new MethodAccessorGenerator()).generateMethod(this.method.getDeclaringClass(), this.method.getName(), this.method.getParameterTypes(), this.method.getReturnType(), this.method.getExceptionTypes(), this.method.getModifiers());this.parent.setDelegate(var3);}

this.numInvocations 的默認值是 0,而 ReflectionFactory.inflationThreshold() 默認是 15,當大于 15 的時候會通過 ASM 技術動態生成 GeneratedMethodAccessor1 類來調用 invoke 方法,但是,因為是動態生成的,我們怎么才能看到這個類實際長什么樣子呢?

Arthas

這個時候,就可以用上阿里的 arthas(阿爾薩斯)了。

首先下載 arthas:

curl?-O?https://alibaba.github.io/arthas/arthas-boot.jar

然后啟動 arthas:

java?-jar?arthas-boot.jar

啟動之后界面長這個樣子:

其中什么 23012, 28436 等是當前環境中現有的 java 進程,然后需要連接到哪個進程就輸前面的編號(1234 啥的),輸了之后回車。那么我首先改寫一下最開始的那個程序,讓他不退出:

package com.example.classstudy;import java.lang.reflect.Method;/*** @author TY*/ public class ReflectionTest {private static int count = 0;public static void foo() {new Exception("test#" + (count++)).printStackTrace();}public static void main(String[] args) throws Exception {Class<?> clz = Class.forName("com.example.classstudy.ReflectionTest");Method method = clz.getMethod("foo");for (int i = 0; i < 20; i++) {method.invoke(null);}System.in.read();} }

重新啟動程序之后,查看 arthas 界面:

可以看到 32480 正是我們運行的程序,輸入編號 2 去連接到該進程:

然后就可以將動態生成的類 dump 下來:

dump?sun.reflect.GeneratedMethodAccessor1

可以看到字節碼被 dump 下來了,找到該文件用 javap 來查看:

javap?-c?-v?-p?-l?GeneratedMethodAccessor1.class

沒有問題,可以查看到,然后剩下的就是人肉翻譯字節碼啦。。。

本篇關于Arthas的使用其實很少,我只是因為學到這個地方簡單的用了下,但是已經感受到了 Arthas 的強大之處,它甚至還支持 web 界面。。。

相當厲害!

Arthas 征文活動火熱進行中

Arthas 官方正在舉行征文活動,如果你有:

  • 使用 Arthas 排查過的問題
  • 對 Arthas 進行源碼解讀
  • 對 Arthas 提出建議
  • 不限,其它與 Arthas 有關的內容

歡迎參加征文活動,還有獎品拿哦~點擊投稿

“阿里巴巴云原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦云原生流行技術趨勢、云原生大規模的落地實踐,做最懂云原生開發者的公眾號。”

總結

以上是生活随笔為你收集整理的Java 虚拟机诊断利器的全部內容,希望文章能夠幫你解決所遇到的問題。

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