ASM应用举例

来源:互联网 发布:咪咕出品的网络剧 编辑:程序博客网 时间:2024/06/06 06:56

1.ASM简介

ASM为Assembly的简写,意思是指装配。ASM指令的含义为汇编指令(泛指Intel 80X86 CPU中的指令集)。 ASM指令是为编程人员编写程序准备的,编译器将会把ASM指令真正的翻译成机器代码(能控制CPU做出操作的代码)。ASM可以操作的粒度在指令级别,具有性能好,灵活度高,功能强大的特点。关于ASM指令集合的具体介绍,参考下面的链接:http://blog.csdn.net/thisinnocence/article/details/50936470 ;大家可以根据自己的情况百度一下。

2.应用举例

ASM到底有什么作用呢?关于java的class文件进行热替换应该或多或少的知道一点,通俗的来讲就是在不关闭服务器的情况下,对class文件内容进行替换,达到增加功能的目的。不清楚的参考下面的链接:

https://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/,具体介绍了热替换的原理和应用举例。热替换操作的对象是java的class文件,而不是指令级别的操作,而ASM是对java文件的指令级别的操作,这样的话速度更快!关于热替换的举例大家可以自己百度一下,在这里列举一个ASM的例子。
背景:统计函数执行时间,将开始和结束时间添加到相应的操作中。
Account.java模拟耗时的函数:
package asmtimer;public class Account {public void operation(){System.out.println("operations.....");try{Thread.sleep(10);}catch(InterruptedException e){e.printStackTrace();}}}
TimeStat计时统计函数:
package asmtimer;public class TimeStat {static ThreadLocal<Long> t=new ThreadLocal<>();public static void start(){t.set(System.currentTimeMillis());}public static void end(){long time=System.currentTimeMillis();System.out.println(Thread.currentThread().getStackTrace()[2]+"speed:");System.out.println(time);}}
       下面是重点,将TimeStat中的函数对Account函数进行及时功能,TimeStatWeaveGenerator类主要是生成合并后的.class文件,里面具有函数统计功能,
package asmtimer;import java.io.File;import java.io.FileOutputStream;import org.objectweb.asm.ClassReader;import org.objectweb.asm.ClassWriter;public class TimeStatWeaveGenerator {public static void main(String[] args) throws Exception{String className=Account.class.getName();ClassReader cr=new ClassReader(className);ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);TimeStatClassAdapter classAdapter=new TimeStatClassAdapter(cw);cr.accept(classAdapter, ClassReader.SKIP_DEBUG);byte[] bytes=cw.toByteArray();FileOutputStream fOutputStream=new FileOutputStream(new File("bin/"+className.replaceAll("\\.", "/")+".class"));fOutputStream.write(bytes);fOutputStream.close();}}
TimeStatClassAdapter类:
package asmtimer;import org.objectweb.asm.ClassAdapter;import org.objectweb.asm.ClassVisitor;import org.objectweb.asm.MethodVisitor;public class TimeStatClassAdapter extends ClassAdapter {public TimeStatClassAdapter(ClassVisitor cv){super(cv);}public MethodVisitor visitMethod(final int access,final String name,final String desc,final String signature,final String[] exceptions){MethodVisitor mv=cv.visitMethod(access, name, desc, signature, exceptions);MethodVisitor wrappedMv=mv;if(mv!=null){if(name.equals("operation")){wrappedMv=new TimeStatMethodAdapter(mv);}}return wrappedMv;}}
TimeStatMethodAdaptor类:
package asmtimer;import org.objectweb.asm.MethodAdapter;import org.objectweb.asm.MethodVisitor;import org.objectweb.asm.Opcodes;public class TimeStatMethodAdapter extends MethodAdapter{public TimeStatMethodAdapter(MethodVisitor ss){super(ss);}@Overridepublic void visitCode(){mv.visitMethodInsn(Opcodes.INVOKESTATIC, "asmtimer/TimeStat", "start", "()V");super.visitCode();}@Overridepublic void visitInsn(int opcode){if(opcode>=Opcodes.IRETURN&&opcode<=Opcodes.RETURN){mv.visitMethodInsn(Opcodes.INVOKESTATIC, "asmtimer/TimeStat", "end", "()V");}mv.visitInsn(opcode);}}
测试类:
package asmtimer;public class RunAccountMain {public static void main(String[] args){Account account=new Account();account.operation();}}
      在没有运行TimeStatWeaveGenerator类,直接运行RunAccountMain类,出现如下信息:
      点击TimeStatWeaveGenerator类将bin对应文件下面的class文件替换掉,再一次运行RunAccountMain类,出现如下信息:
可以通过javap命令查看字节码:
由于生成的文件比较长,只粘贴一部分,大家可以自己运行一下。原来的Account类字节码:
增加时间统计功能后的Account:

3.相关资源


里面涉及的东西比较多,下面给大家提供一些关于ASM和一些类的资源链接:

1)Asm多继承举例:http://www.cnblogs.com/liuling/archive/2013/05/31/asmMutilExtends.html

2)Asm用户手册:http://download.forge.objectweb.org/asm/asm4-guide.pdf

3)Asm3.2 Api: http://asm.ow2.org/asm32/javadoc/user/index.html

4) Asm 源码地址:https://github.com/marchof/asm

5) Asm3.0中文API:https://wenku.baidu.com/view/bf486c4577232f60ddcca133.html


        这些知识个人的学习总结,主要参考《实战虚拟机-jvm故障诊断与性能优化》,若有错误或者改进之处,请多多指导,谢谢!!!

原创粉丝点击