作者 | 小白一只

【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 虚拟机诊断利器相关推荐

  1. Arthas(Java 应用诊断利器)

    文章目录 Arthas 使用背景 Arthas(阿尔萨斯)能做什么? Arthas Spring Boot Starter Arthas Arthas 是由Alibaba开源的Java监控诊断工具,通 ...

  2. ali arthas 火焰图_带你上手阿里开源的 Java 诊断利器:Arthas

    本文适合有 Java 基础知识的人群. 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>[1]系列,今天给大家带来一款阿里开源的 Java 诊断利器 ...

  3. Alibaba Java诊断利器Arthas实践--使用redefine排查应用奇怪的日志来源

    2019独角兽企业重金招聘Python工程师标准>>> 背景 随着应用越来越复杂,依赖越来越多,日志系统越来越混乱,有时会出现一些奇怪的日志,比如: [] [] [] No cred ...

  4. java为什么打不开jar_带你上手阿里开源的 Java 诊断利器:Arthas

    本文适合有 Java 基础知识的人群. 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>[1]系列,今天给大家带来一款阿里开源的 Java 诊断利器 ...

  5. idea 项目jar反编译java_带你上手阿里开源的 Java 诊断利器:Arthas

    本文适合有 Java 基础知识的人群. 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>系列,今天给大家带来一款阿里开源的 Java 诊断利器 Art ...

  6. java虚拟机内存监控_深入理解JVM虚拟机9:JVM监控工具与诊断实践

    本文转自: https://juejin.im/post/59e6c1f26fb9a0451c397a8c 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到 ...

  7. sas java 虚拟机异常_深入理解JAVA虚拟机之异常诊断

    常见的JAVA虚拟机HotSpot虚拟机运行时数据库由5部分构成:方法区,堆,虚拟机栈,本地方法栈,程序计数器.下面列举各个部分可能出现的异常及其出现原因. 1.方法区存放的已被虚拟机加载的类型信息, ...

  8. 性能诊断利器 JProfiler 快速入门和最佳实践

    背景 性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益.Java 作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关注.可 ...

  9. windows7内存诊断工具有用吗_性能诊断利器 JProfiler 快速入门和实践

    云栖君导读:性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益.Java 作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关 ...

最新文章

  1. 【c语言】蓝桥杯算法提高 淘淘的名单
  2. spark 持久化 mysql_Spark读取数据库(Mysql)的四种方式讲解
  3. redis - 基础
  4. vue2.0 MintUI安装和基本使用
  5. 通过Redis、Memcache的 incr 原子操作防刷机制的使用差别
  6. 分布式系统架构常识:CAP理论
  7. 前端windows下常用的CMD 命令归纳
  8. SpringMVC中拦截/和拦截/*的区别
  9. python找思路_python 爬取贝壳的一些思路和方法设计(用地址找到小区名字)
  10. Ubuntu环境搭建零:安装Linux虚拟机
  11. conda命令没找到的处理方案
  12. 申通回应被京东“封杀”;Kotlin 1.4.0 发布 | 极客头条
  13. 也谈UpdatePanel与UrlRewrite一起work时出现Form Action属性的问题
  14. oracle mysql认证考试流程_oraclemysql认证考试流程
  15. Word插入特殊符号
  16. 使用傅里叶模态法分析闪耀光栅
  17. Web前端大作业—— 饮食餐饮网站 咖啡网站pc端带轮播(5个页面)HTML+CSS+JavaScript 学生美食网页设计作品 学生餐饮文化网页模板
  18. Day04_Manuals for Python@lisongye - list列表
  19. 海外引流怎么做?巨象指纹浏览器助你,人人都是产品经理
  20. 小学生学计算机图片大全集,小学生电脑绘画作品欣赏

热门文章

  1. Windows进程与线程学习笔记(六)—— 线程切换
  2. MySQL数据库恢复(LOAD DATA)
  3. 【Linux】 iptables vs firewalld
  4. Sublime Text 3143 注册码
  5. 1、SELECT:数据表查询语句
  6. 用substr()函数高效的输出一个字符串的所用子串
  7. 第二章 Matlab变量
  8. Bootstrap的引用文件
  9. unity能连jsp吗_Unity3D与JSP TomCat服务器传递数据和文件( 一 ) 建立Java服务器
  10. 实战上亿数据,如何实现秒查!