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
