文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

一篇文章解密 Arthas 实现原理

2024-12-02 00:32

关注

前言

在之前文章中介绍了 Arthas 应用诊断利器--入门和常用骚操作,想必大家同我一样对 Arthas 这么强大的功能所折服(如何做到无需重启 attach 到 JVM、又如何实现各种监听和统计等功能),今天我们就来对 Arthash 的实现进行解密。提前透露下今天重要的角色:Instrument、ASM。

Instrument

带着问题 Arthas 如何做到无需重启 attach 到 JVM 开始进入正题,首先先介绍下 Instrument。

Instrumentation类提供控制Java语言程序代码的服务。Instrumentation可以实现在方法插入额外的字节码从而达到收集使用中的数据到指定工具的目的。由于插入的字节码是附加的,这些更变不会修改原来程序的状态或者行为。通过这种方式实现的良性工具包括监控代理、分析器、覆盖分析程序和事件日志记录程序等等。

简单来说,Instrument 就是「针对已有的类修改其字节码来增强其逻辑,从开发者的角度可以理解为 JVM 层面的 AOP 编程」。开源的很多 APM(Application Performance Monitor) 框架如 SkyWalking、PinPoint 等都是通过java.lang.instrument包提供的字节码增强功能来实现的,大部分情况下 我们都是使用 Instrument 字节码插桩的功能。

  1. Jdk5 开始引入 java.lang.instrument 包,一开始只有 premain 的方式(通过命令行使用外部代理jar包 )
  2. 新建/在现有的项目中,编写 premain 函数 public static void premain(String agentArgs, Instrumentation inst)。
  3. 将项目打成 jar 包,并引入 Maven 插件 maven-jar-plugin 指定 Premain-Class。

通过指定Agent运行 java -javaagent:代理Jar包的路径 [=传入premain的参数] yourTarget.jar

Jdk6 之后针对这点进行优化,不再需要在通过命令 -javaagent 的方式指定引入代理 Jar,而是通过使用 agentmain 在运行时通过attach工具激活指定代理。就可以通过 addTransformer,retransformClasses,redefineClasses等方式对字节码进行增强和热替换了。

  1. 新建/在现有的项目中,编写 agentmain 函数 public static void agentmain(String agentArgs, Instrumentation inst)。
  2. 将项目打成 jar 包,并引入 Maven 插件 maven-jar-plugin 指定 Premain-Class。
  3. 通过attach工具直接加载Agent。

「简单的提下 Instrument原理:」

instrument 的底层实现依赖于 JVMTI(JVM Tool Interface),它是JVM暴露出来的一些供用户扩展的接口集合,JVMTI是基于事件驱动的, JVM 每执行到一定的逻辑就会调用一些事件的回调接口(如果有的话),这些接口可以供开发者去扩展自己的逻辑。JVMTIAgent 是一个利用 JVMTI 暴露出来的接口提供了代理启动时加载(agent on load)、代理通过 attach 形式加载(agent on attach)和代理卸载(agent on unload)功能的动态库。而instrument agent可以理解为一类 JVMTIAgent 动态库,别名是 JPLISAgent(Java Programming Language Instrumentation Services Agent),也就是专门为java语言编写的插桩服务提供支持的代理。

ASM

既然已经有了重写类的入口(Instrument),那么只需要结合第三方的字节码编译工具即可完成想要的功能了,Arthas 就是通过 ASM 用来动态生成class或者增强class,比如常用的 Gradle 在运行时基于 ASM 运行时生成一些类、 CGLib 也是基于 ASM 实现的(插一个题外话:Jdk Proxy而是基于是「反射机制」实现的)

「ASM」是一个通用的 Java 字节码操作和分析框架。它可用于直接以二进制形式修改现有类或动态生成类。ASM 提供了一些常见的字节码转换和分析算法,可以从中构建自定义的复杂转换和代码分析工具。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。

ASM 提供与其他 Java 字节码框架类似的功能,但侧重于 性能。因为它被「设计和实现得尽可能小和尽可能快」,所以它「非常适合在动态系统中使用」(但当然也可以以静态方式使用,例如在编译器中)。ASM 字节码增强技术主要是用来反射的时候提升性能的,如果单纯用jdk的反射调用,性能是非常低下的,而使用字节码增强技术后反射调用的时间已经基本可以与直接调用相当。

ASM:

https://asm.ow2.io/index.html。

「ASM 字节码处理流程:」目标类 class bytes -> ClassReader解析 -> ClassVisitor增强修改字节码 -> ClassWriter生成增强后的 class bytes。

「Arthas 如何做到无需重启 attach 到 JVM (ASM + Instrument 处理流程):」

目标类 class bytes -> ClassReader解析 -> ClassVisitor增强修改字节码 -> ClassWriter生成增强后的 class bytes -> 通过Instrument解析加载为新的Class.

来源:Java架构师进阶编程内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯