(一)初识arthas

Arthas(阿尔萨斯) 能为你做什么?文档

Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。
当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

  1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  3. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  4. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  5. 是否有一个全局视角来查看系统的运行状况?
  6. 有什么办法可以监控到JVM的实时运行状态?
  7. 怎么快速定位应用的热点,生成火焰图?

Arthas支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

1. Arthas原理?来源

  • Instrument和Attach API

    • Jdk5增加了一个包java.lang.instrument,提供了对Jvm底层组件的访问能力,Instrument要求在运行前利用命令行参数或者系统参数设置代理类,VM启动完成之后(绝大多数类加载前)初始化。
      开发基于instrument的应用,需要这么几个步骤:
      编写premain函数
      jar文件打包,制定Premain-Class
      使用-javaagent参数启动
    • Jdk6以后,针对这点进行了改进,开发者可以在main函数执行之后再启动自己的Instrument应用,入口是agentmain函数。arthas就是通过这个实现的。
      之后就可以通过addTransformer,retransformClasses,redefineClasses等方式对字节码进行增强和热替换了。
  • ASM

    • ASM是一个Java字节码操作框架,用来动态生成class或者增强class,cglib的底层就是它,arthas也是通过它实现对class的增强的。
    • Arthas增强功能的核心是Enhancer和AdviceWeaver这两个类,对方法进行Aop织入,达到watch,trace等效果。
  • JVMTI

    • 然后呢?还没有结束,继续看一下attach下面一层是什么。
    • JVMTI(JVM Tool Interface)是Java虚拟机所提供的native接口,提供了可用于debug和profiler的能力,是实现调试器和其他运行态分析工具的基础,Instrument就是对它的封装。
    • JVMTI又是在JPDA(Java Platform Debugger Architecture)之下的三层架构之一,JVMTI,JDWP,JDI。可以参考IBM系列文章:深入 Java 调试体系
    • 我们常用的debug参数-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8080,其实就是加载了jdwp的lib,开启了调试端口,然后就可以通过JDI接口进行交互调试。

2.火焰图原理(async-profiler)?

  • Arthas的功能其实到上面已经结束啦,但是arthas还集成了另一个大杀器,async-profiler(IDEA的 JVM Profiler也是集成的这个),可以直接对java热点方法生成火焰图!
  • 通常Arthas的trace命令用来定位单点性能问题,但是如果系统整体启动、运行都很慢,那Arthas也力不从心了,需要对系统全局做性能热点分析和优化,这个时候火焰图就派上了用场。
  • 对于大部分开源Profiler,原理其实就是循环打印线程堆栈,然后统计各方法出现的频率,比如说Jprofiler的Simpling模式(Instrumentation模式是对所有类进行增强,比较精准一些,但是性能影响较大),网上也有一些shell工具,可以打印堆栈生成数据表,导入Excel用透视图表进行分析。
  • 这些方式有一个问题,就是JVM只会在安全点(safe point)进行采样,如果某些方法执行时间极短,但是频率很高,实际占用了大量的cpu time,但是采样周期不能无限调小,导致大量的样本调用堆栈并不存在这些高频小方法,导致最终统计结果无法反应真实的cpu热点。
 JVM安全点如何定义和划分,R大的回答:https://www.zhihu.com/question/29268019/answer/43762165
  • Async profiler则是通过JVMTI + AsyncGetCallTrace(非JVM标准函数)实现的,基本上可以采样任何时期的stack状态,Linux环境下结合perf_event还能做到同时采样Java栈和Native栈,同时分析Native代码的热点。生成的调用堆栈形式如下,左边是调用栈方法排列,右边是样本出现次数:base_func;func1;func2;func3 10base_func;funca;funcb 15然后通过FlameGraph等工具处理,就可以生成火焰图了。
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页