Java性能监控系列——java.lang.instrument

  Instrumentation是Java5提供的新特性。使用Instrumentation,开发者可以构建一个代理,用来监测运行在JVM上的程序。监测一般是通过在执行某个类文件之前,对该类文件的字节码进行适当的修改进行的。

       java.lang.instrument中需要关注的是ClassFileTransformer和Instrumentation接口。每个代理类必须实现 ClassFileTransformer接口,这个接口提供了一个transform方法:
[java]  view plain  copy
  1. byte[] transform(ClassLoader loader,  
  2.                  String className,  
  3.                  Class<?> classBeingRedefined,  
  4.                  ProtectionDomain protectionDomain,  
  5.                  byte[] classfileBuffer)  
  6.                  throws IllegalClassFormatException  

通过这个方法,代理可以得到虚拟机载入的类的字节码,并可对其进行修改,完成字节码级的修改。各个参数的含义为:
loader:将被转换的类的类装载器,如果是启动类装载器则此参数可以为空;
className:类名字,不过这是JVM规范定义的全限名字如java/util/List
protectionDomain:保护域,跟安全有关;
classFileBuffer:这个便是被代理类字节码流,正是通过操作这个buffer完成对字节码的修改;
对于函数的返回值,如果返回null,则表示不对类的字节码做任何的修改,否则应该返回修改过的byte[]对象。
除了实现ClassFileTransformer接口外,我们还需要提供一个公共的静态方法:
public static void premain(String agentArgs, Instrumentation inst)
</pre><pre class="displaycode" name="code" style="white-space: pre-wrap; word-wrap: break-word; overflow: auto; margin-top: 0px; width: 694px; margin-bottom: 0px;">一般会在这个方法中创建一个代理对象,通过Instrumentation对象的addTransformer()方法,将创建的代理对象再传递给虚拟机。


一个简单的演示实例:
</pre><pre class="displaycode" name="code" style="white-space: pre-wrap; word-wrap: break-word; overflow: auto; margin-top: 0px; width: 694px; margin-bottom: 0px;">agent类实现:
[java]  view plain  copy
  1. public class HelloWorld implements ClassFileTransformer {  
  2.   
  3.     @Override  
  4.     public byte[] transform(ClassLoader loader, String className,  
  5.             Class<?> classBeingRedefined, ProtectionDomain protectionDomain,  
  6.             byte[] classfileBuffer) throws IllegalClassFormatException {  
  7.           
  8.         System.out.println("java.lang.instrument, hello world!");  
  9.           
  10.         return null;  
  11.     }  
  12.       
  13.     public static void premain(String args,Instrumentation inst){  
  14.         inst.addTransformer(new HelloWorld());  
  15.     }  
  16.   
  17. }  

监控类:
[java]  view plain  copy
  1. public class Example {  
  2.       
  3.     public static void main(String[] args){  
  4.         System.out.println("main class of proxy!");  
  5.     }  
  6.       
  7. }  

将agent类HelloWorld编译成可运行的jar(helloworld.jar),这里注意在manifest文件中添加premain入口,也即其配置为:
</pre><pre class="displaycode" name="code" style="white-space: pre-wrap; word-wrap: break-word; overflow: auto; margin-top: 0px; width: 694px; margin-bottom: 0px;"><div class="dp-highlighter bg_plain" style="font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; width: 687.047px; overflow: auto; padding-top: 1px; margin: 18px 0px !important; background-color: rgb(231, 229, 220);"><div class="bar" style="padding-left: 45px;"><div class="tools" style="padding: 3px 8px 10px 10px; font-stretch: normal; font-size: 9px; line-height: normal; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; color: silver; border-left-width: 3px; border-left-style: solid; border-left-color: rgb(108, 226, 108); background-color: rgb(248, 248, 248);"><strong>[plain]</strong> <a target=_blank href="http://blog.csdn.net/shi1122/article/details/7981194#" class="ViewSource" title="view plain" style="color: rgb(160, 160, 160); text-decoration: none; border: none; padding: 1px; margin: 0px 10px 0px 0px; font-size: 9px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url("images/default/ico_plain.gif"); background-attachment: initial; background-color: inherit; background-size: initial; background-origin: initial; background-clip: initial; background-position: 0% 0%; background-repeat: no-repeat;">view plain</a><span data-mod="popu_168"> <a target=_blank href="http://blog.csdn.net/shi1122/article/details/7981194#" class="CopyToClipboard" title="copy" style="color: rgb(160, 160, 160); text-decoration: none; border: none; padding: 1px; margin: 0px 10px 0px 0px; font-size: 9px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url("images/default/ico_copy.gif"); background-attachment: initial; background-color: inherit; background-size: initial; background-origin: initial; background-clip: initial; background-position: 0% 0%; background-repeat: no-repeat;">copy</a></span><div style="position: absolute; left: 725px; top: 2149px; width: 18px; height: 18px; z-index: 99;"></div><span data-mod="popu_169"> </span></div></div><ol start="1" style="padding: 0px; border: none; color: rgb(92, 92, 92); margin: 0px 0px 1px 45px !important; background-color: rgb(255, 255, 255);"><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;">Manifest-Version: 1.0  </span></span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; background-color: rgb(248, 248, 248);"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;">Premain-Class: cn.dstrace.instrument.HelloWorld  </span></li></ol></div>
</pre><pre class="displaycode" name="code" style="white-space: pre-wrap; word-wrap: break-word; overflow: auto; margin-top: 0px; width: 694px; margin-bottom: 0px;">完成这些步骤以后,通过java -javaagent:helloworld.jar cn.dstrace.instrument.Example运行,则可看到结果:

这里只是简单的演示了java.lang.instrument是怎么作用到被代理类的,后面讲通过字节码操作工具asm来实现一个具体的应用实例,到时候估计就明白了其强大之处,其实在java的各种性能监控工具中都有instrument的身影,如jconsole等
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值