ASM在游戏服务器的使用
发表于2017-10-19
下面给大家介绍的是ASM在游戏服务器的使用,ASM 是一个 Java 字节码操控框架,它能够以二进制形式修改已有类或者动态生成类。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。
不过ASM在创建class字节码的过程中,操纵的级别是底层JVM的汇编指令级别,这要求ASM使用者要对class组织结构和JVM汇编指令有一定的了解。
而EsotericSoftware的reflectasm帮忙跨过了这个障碍,使用ASM起来非常方便。
方法级别的反射原本如下写法:
Method method=instance.getClass().getMethod("addName"); method.setAccessible(true); method.invoke(instance, "Awesome McLovin"); method.setAccessible(false);
用Reflectasm后,调整为如下,是不是很简单呢?
Object instance =... MethodAccess access = MethodAccess.get(instance.getClass()); int addNameIndex = access.getIndex("addName",access.getParameterTypes()); access.invoke(someObject, addNameIndex, "Awesome McLovin");在我们游戏服务器中,事件分发,异步任务,后台HTTP指令,玩家指令 在服务器起来的时候是分别注册好了,数据路由到这些底层功能后,处理时,本质上就是找到相应的方法method,然后invoke相应的数据,获得结果。
原先我们是用了JAVA原生的反射机制,也就是Method.invoke(Object instance, Object... args),改成了ASM后,性能得到大幅提升,主要是修改了其中的一个类实现:
public class MethodWrapper { private MethodAccess access; private int index;// 方法索引 private Object instance; private Class<?> paramClazz;// 参数类型 private String name; public MethodWrapper(Method method, Object instance) { this.name=method.getName(); this.access = MethodAccess.get(instance.getClass()); this.index = access.getIndex(method.getName(), method.getParameterTypes()); this.instance = instance; this.paramClazz = method.getParameterTypes()[0]; } public Object invoke(Object... args) { Object ret = null; if (args == null) { // 无参数调用 ret = access.invoke(instance, index); } else { // 有参数调用 ret = access.invoke(instance, index, args); } return ret; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Class<?> getParamClazz() { return paramClazz; } public void setParamClazz(Class<?> paramClazz) { this.paramClazz = paramClazz; } }进行压力测试后,对比结果如下:
耗时降低到了原先的1/3不到,效果非常好,为什么我们不选用其他的字节码操控框架呢,以下是网上的一个性能对比:
Framework | First time | Later times |
Javassist | 257 | 5.2 |
BCEL | 473 | 5.5 |
ASM | 62.4 | 1.1 |
这张表表明,ASM的性能远远超过了其他框架,不仅是第一次的运行,后续的反复执行照样表现出色。
http://blog.csdn.net/jiangguilong2000/article/details/49509425