ASM应用举例

2019-04-14 17:41发布

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 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); } @Override public void visitCode(){ mv.visitMethodInsn(Opcodes.INVOKESTATIC, "asmtimer/TimeStat", "start", "()V"); super.visitCode(); } @Override public 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故障诊断与性能优化》,若有错误或者改进之处,请多多指导,谢谢!!!