JavaAgent是一个JVM插件,一种专门精心制作的.jar文件,它能够利用jvm提供的 Instrumentation API(Java1.5开始提供)。Agent分为2种:主程序运行前的Agent,主程序之后运行的Agent(Jdk1.6增加)。
主程序之前的Agent
写一个Agent
1 | public class PreAgent{ |
主程序
1 | public class Main{ |
编写MANIFEST.MF文件
1 | group 'com.hardydou.learn' |
打包
1 | agent.jar |
运行
为主函数添加jvm参数
1 | -javaagent: 路径/preAgent.jar=params |
输出
1 | permain = params |
主程序之后的代理程序
启动前的案例应用还是有点憋屈,至少需要重启一次应用。然而一个异常可能需要程序运行出发某一些条件后才会出现异常。这时就充满了不确定性。主程序之后的代理程序就比较爽了。
编写Agent
1 | //方法名不可以变 |
修改MAINFEST.MF文件
添加
1 | Agent-Class: com.hardydou.agent.PostAgent |
打包
1 | agent.jar |
运行
1 | //可以通过jps获取 |
输出
你会发现在Agent的线程里面不会输出任何东西,有问题?别着急,内容会在Target线程输出。
进阶
ClassFileTransformer
在类的字节码载入jvm前会调用ClassFileTransformer的transform方法,从而实现修改原类方法的功能。
衍生
JProfiler
JProfiler 是一个商业的主要用于检查和跟踪系统(限于Java开发的)的性能的工具。JProfiler可以通过时时的监控系统的内存使用情况,随时监视垃圾回收,线程运行状况等手段,从而很好的监视JVM运行情况及其性能。
Jvisualvm
VisualVM 是Netbeans的profile子项目,已在JDK6.0 update 7 中自带(java启动时不需要特定参数,监控工具在bin/jvisualvm.exe),能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的对象,反向查看分配的堆栈(如100个String对象分别由哪几个对象分配出来的)。
BTrace
原理图
Arthas(推荐)
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
Arthas文档