`
wsmajunfeng
  • 浏览: 491971 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

动态代理方案性能对比

 
阅读更多

转:http://code.alibabatech.com/blog/experience_1054/dynamic_proxy_performance.html

 

因服务框架需要用动态代理生成客户端接口的stub,所以做了一下性能评测,
动态代理工具比较成熟的产品有:
JDK自带的,ASM,CGLIB(基于ASM包装),JAVAASSIST,
使用的版本分别为:
JDK-1.6.0_18-b07, ASM-3.3, CGLIB-2.2, JAVAASSIST-3.11.0.GA

(一) 测试结果:
数据为执行三次,每次调用一千万次代理方法的结果,测试代码后面有贴出。

(1) PC机测试结果:Linux 2.6.9-42.ELsmp(32bit), 2 Cores CPU(Intel Pentium4 3.06GHz)

Create JDK Proxy: 13 ms
Create CGLIB Proxy: 217 ms
Create JAVAASSIST Proxy: 99 ms
Create JAVAASSIST Bytecode Proxy: 168 ms
Create ASM Proxy: 3 ms
================
Run JDK Proxy: 2224 ms, 634,022 t/s
Run CGLIB Proxy: 1123 ms, 1,255,623 t/s
Run JAVAASSIST Proxy: 3212 ms, 438,999 t/s
Run JAVAASSIST Bytecode Proxy: 206 ms, 6,844,977 t/s
Run ASM Bytecode Proxy: 209 ms, 6,746,724 t/s
—————-
Run JDK Proxy: 2169 ms, 650,099 t/s
Run CGLIB Proxy: 1059 ms, 1,331,506 t/s
Run JAVAASSIST Proxy: 3328 ms, 423,697 t/s
Run JAVAASSIST Bytecode Proxy: 202 ms, 6,980,521 t/s
Run ASM Bytecode Proxy: 206 ms, 6,844,977 t/s
—————-
Run JDK Proxy: 2174 ms, 648,604 t/s
Run CGLIB Proxy: 1032 ms, 1,366,342 t/s
Run JAVAASSIST Proxy: 3119 ms, 452,088 t/s
Run JAVAASSIST Bytecode Proxy: 207 ms, 6,811,910 t/s
Run ASM Bytecode Proxy: 207 ms, 6,811,910 t/s
—————-

(2) 服务器测试结果:Linux 2.6.18-128.el5xen(64bit), 16 Cores CPU(Intel Xeon E5520 2.27GHz)

Create JDK Proxy: 7 ms
Create CGLIB Proxy: 86 ms
Create JAVAASSIST Proxy: 36 ms
Create JAVAASSIST Bytecode Proxy: 57 ms
Create ASM Proxy: 1 ms
================
Run JDK Proxy: 235 ms, 6,000,278 t/s
Run CGLIB Proxy: 234 ms, 6,025,920 t/s
Run JAVAASSIST Proxy: 459 ms, 3,072,037 t/s
Run JAVAASSIST Bytecode Proxy: 71 ms, 19,860,076 t/s
Run ASM Bytecode Proxy: 72 ms, 19,584,241 t/s
—————-
Run JDK Proxy: 298 ms, 4,731,763 t/s
Run CGLIB Proxy: 134 ms, 10,522,876 t/s
Run JAVAASSIST Proxy: 406 ms, 3,473,067 t/s
Run JAVAASSIST Bytecode Proxy: 67 ms, 21,045,752 t/s
Run ASM Bytecode Proxy: 66 ms, 21,364,627 t/s
—————-
Run JDK Proxy: 282 ms, 5,000,231 t/s
Run CGLIB Proxy: 133 ms, 10,601,995 t/s
Run JAVAASSIST Proxy: 406 ms, 3,473,067 t/s
Run JAVAASSIST Bytecode Proxy: 67 ms, 21,045,752 t/s
Run ASM Bytecode Proxy: 67 ms, 21,045,752 t/s
—————-

(二) 测试结论:
1. ASM和JAVAASSIST字节码生成方式不相上下,都很快,是CGLIB的5倍。
2. CGLIB次之,是JDK自带的两倍。
3. JDK自带的再次之,因JDK1.6对动态代理做了优化,如果用低版本JDK更慢,要注意的是JDK也是通过字节码生成来实现动态代理的,而不是反射。
4. JAVAASSIST提供者动态代理接口最慢,比JDK自带的还慢。
(这也是为什么网上有人说JAVAASSIST比JDK还慢的原因,用JAVAASSIST最好别用它提供的动态代理接口,而可以考虑用它的字节码生成方式)

(三) 差异原因:
各方案生成的字节码不一样,
像JDK和CGLIB都考虑了很多因素,以及继承或包装了自己的一些类,
所以生成的字节码非常大,而我们很多时候用不上这些,
而手工生成的字节码非常小,所以速度快,
具体的字节码对比,后面有贴出,可自行分析。

(四) 最终选型:
最终决定使用JAVAASSIST的字节码生成代理方式,
虽然ASM稍快,但并没有快一个数量级,
而JAVAASSIST的字节码生成方式比ASM方便,
JAVAASSIST只需用字符串拼接出Java源码,便可生成相应字节码,
而ASM需要手工写字节码。

(五) 测试代码:

public interface CountService {

int count();

}

public class CountServiceImpl implements CountService {

private int count = 0;

public int count() {
return count ++;
}
}

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.text.DecimalFormat;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import javassist.util.proxy.ProxyObject;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class DynamicProxyPerformanceTest {

public static void main(String[] args) throws Exception {
CountService delegate = new CountServiceImpl();

long time = System.currentTimeMillis();
CountService jdkProxy = createJdkDynamicProxy(delegate);
time = System.currentTimeMillis() – time;
System.out.println(“Create JDK Proxy: ” + time + ” ms”);

time = System.currentTimeMillis();
CountService cglibProxy = createCglibDynamicProxy(delegate);
time = System.currentTimeMillis() – time;
System.out.println(“Create CGLIB Proxy: ” + time + ” ms”);

time = System.currentTimeMillis();
CountService javassistProxy = createJavassistDynamicProxy(delegate);
time = System.currentTimeMillis() – time;
System.out.println(“Create JAVAASSIST Proxy: ” + time + ” ms”);

time = System.currentTimeMillis();
CountService javassistBytecodeProxy = createJavassistBytecodeDynamicProxy(delegate);
time = System.currentTimeMillis() – time;
System.out.println(“Create JAVAASSIST Bytecode Proxy: ” + time + ” ms”);

time = System.currentTimeMillis();
CountService asmBytecodeProxy = createAsmBytecodeDynamicProxy(delegate);
time = System.currentTimeMillis() – time;
System.out.println(“Create ASM Proxy: ” + time + ” ms”);
System.out.println(“================”);

for (int i = 0; i < 3; i++) {
test(jdkProxy, “Run JDK Proxy: “);
test(cglibProxy, “Run CGLIB Proxy: “);
test(javassistProxy, “Run JAVAASSIST Proxy: “);
test(javassistBytecodeProxy, “Run JAVAASSIST Bytecode Proxy: “);
test(asmBytecodeProxy, “Run ASM Bytecode Proxy: “);
System.out.println(“—————-”);
}
}

private static void test(CountService service, String label)
throws Exception {
service.count(); // warm up
int count = 10000000;
long time = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
service.count();
}
time = System.currentTimeMillis() – time;
System.out.println(label + time + ” ms, ” + new DecimalFormat().format(count * 1000 / time) + ” t/s”);
}

private static CountService createJdkDynamicProxy(final CountService delegate) {
CountService jdkProxy = (CountService) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
new Class[] { CountService.class }, new JdkHandler(delegate));
return jdkProxy;
}

private static class JdkHandler implements InvocationHandler {

final Object delegate;

JdkHandler(Object delegate) {
this.delegate = delegate;
}

public Object invoke(Object object, Method method, Object[] objects)
throws Throwable {
return method.invoke(delegate, objects);
}
}

private static CountService createCglibDynamicProxy(final CountService delegate) throws Exception {
Enhancer enhancer = new Enhancer();
enhancer.setCallback(new CglibInterceptor(delegate));
enhancer.setInterfaces(new Class[] { CountService.class });
CountService cglibProxy = (CountService) enhancer.create();
return cglibProxy;
}

private static class CglibInterceptor implements MethodInterceptor {

final Object delegate;

CglibInterceptor(Object delegate) {
this.delegate = delegate;
}

public Object intercept(Object object, Method method, Object[] objects,
MethodProxy methodProxy) throws Throwable {
return methodProxy.invoke(delegate, objects);
}
}

private static CountService createJavassistDynamicProxy(final CountService delegate) throws Exception {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setInterfaces(new Class[] { CountService.class });
Class<?> proxyClass = proxyFactory.createClass();
CountService javassistProxy = (CountService) proxyClass.newInstance();
((ProxyObject) javassistProxy).setHandler(new JavaAssitInterceptor(delegate));
return javassistProxy;
}

private static class JavaAssitInterceptor implements MethodHandler {

final Object delegate;

JavaAssitInterceptor(Object delegate) {
this.delegate = delegate;
}

public Object invoke(Object self, Method m, Method proceed,
Object[] args) throws Throwable {
return m.invoke(delegate, args);
}
}

private static CountService createJavassistBytecodeDynamicProxy(CountService delegate) throws Exception {
ClassPool mPool = new ClassPool(true);
CtClass mCtc = mPool.makeClass(CountService.class.getName() + “JavaassistProxy”);
mCtc.addInterface(mPool.get(CountService.class.getName()));
mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));
mCtc.addField(CtField.make(“public ” + CountService.class.getName() + ” delegate;”, mCtc));
mCtc.addMethod(CtNewMethod.make(“public int count() { return delegate.count(); }”, mCtc));
Class<?> pc = mCtc.toClass();
CountService bytecodeProxy = (CountService) pc.newInstance();
Field filed = bytecodeProxy.getClass().getField(“delegate”);
filed.set(bytecodeProxy, delegate);
return bytecodeProxy;
}

private static CountService createAsmBytecodeDynamicProxy(CountService delegate) throws Exception {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
String className = CountService.class.getName() + “AsmProxy”;
String classPath = className.replace(‘.’, ‘/’);
String interfacePath = CountService.class.getName().replace(‘.’, ‘/’);
classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, classPath, null, “java/lang/Object”, new String[] {interfacePath});

MethodVisitor initVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, “<init>”, “()V”, null, null);
initVisitor.visitCode();
initVisitor.visitVarInsn(Opcodes.ALOAD, 0);
initVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, “java/lang/Object”, “<init>”, “()V”);
initVisitor.visitInsn(Opcodes.RETURN);
initVisitor.visitMaxs(0, 0);
initVisitor.visitEnd();

FieldVisitor fieldVisitor = classWriter.visitField(Opcodes.ACC_PUBLIC, “delegate”, “L” + interfacePath + “;”, null, null);
fieldVisitor.visitEnd();

MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, “count”, “()I”, null, null);
methodVisitor.visitCode();
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
methodVisitor.visitFieldInsn(Opcodes.GETFIELD, classPath, “delegate”, “L” + interfacePath + “;”);
methodVisitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, interfacePath, “count”, “()I”);
methodVisitor.visitInsn(Opcodes.IRETURN);
methodVisitor.visitMaxs(0, 0);
methodVisitor.visitEnd();

classWriter.visitEnd();
byte[] code = classWriter.toByteArray();
CountService bytecodeProxy = (CountService) new ByteArrayClassLoader().getClass(className, code).newInstance();
Field filed = bytecodeProxy.getClass().getField(“delegate”);
filed.set(bytecodeProxy, delegate);
return bytecodeProxy;
}

private static class ByteArrayClassLoader extends ClassLoader {

public ByteArrayClassLoader() {
super(ByteArrayClassLoader.class.getClassLoader());
}

public synchronized Class<?> getClass(String name, byte[] code) {
if (name == null) {
throw new IllegalArgumentException(“”);
}
return defineClass(name, code, 0, code.length);
}

}
}

(六) 字节码对比

(1) JDK生成的字节码:

public final class $Proxy0 extends java.lang.reflect.Proxy implements com.alibaba.test.performance.dynamicproxy.CountService{
public $Proxy0(java.lang.reflect.InvocationHandler) throws ;
Code:
0: aload_0
1: aload_1
2: invokespecial #8; //Method java/lang/reflect/Proxy.”":(Ljava/lang/reflect/InvocationHandler;)V
5: return

public final boolean equals(java.lang.Object) throws ;
Code:
0: aload_0
1: getfield #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
4: aload_0
5: getstatic #20; //Field m1:Ljava/lang/reflect/Method;
8: iconst_1
9: anewarray #22; //class java/lang/Object
12: dup
13: iconst_0
14: aload_1
15: aastore
16: invokeinterface #28, 4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
21: checkcast #30; //class java/lang/Boolean
24: invokevirtual #34; //Method java/lang/Boolean.booleanValue:()Z
27: ireturn
28: athrow
29: astore_2
30: new #42; //class java/lang/reflect/UndeclaredThrowableException
33: dup
34: aload_2
35: invokespecial #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V
38: athrow
Exception table:
from to target type
0 28 28 Class java/lang/Error

0 28 28 Class java/lang/RuntimeException

0 28 29 Class java/lang/Throwable

public final int count() throws ;
Code:
0: aload_0
1: getfield #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
4: aload_0
5: getstatic #50; //Field m3:Ljava/lang/reflect/Method;
8: aconst_null
9: invokeinterface #28, 4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
14: checkcast #52; //class java/lang/Integer
17: invokevirtual #55; //Method java/lang/Integer.intValue:()I
20: ireturn
21: athrow
22: astore_1
23: new #42; //class java/lang/reflect/UndeclaredThrowableException
26: dup
27: aload_1
28: invokespecial #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V
31: athrow
Exception table:
from to target type
0 21 21 Class java/lang/Error

0 21 21 Class java/lang/RuntimeException

0 21 22 Class java/lang/Throwable

public final int hashCode() throws ;
Code:
0: aload_0
1: getfield #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
4: aload_0
5: getstatic #59; //Field m0:Ljava/lang/reflect/Method;
8: aconst_null
9: invokeinterface #28, 4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
14: checkcast #52; //class java/lang/Integer
17: invokevirtual #55; //Method java/lang/Integer.intValue:()I
20: ireturn
21: athrow
22: astore_1
23: new #42; //class java/lang/reflect/UndeclaredThrowableException
26: dup
27: aload_1
28: invokespecial #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V
31: athrow
Exception table:
from to target type
0 21 21 Class java/lang/Error

0 21 21 Class java/lang/RuntimeException

0 21 22 Class java/lang/Throwable

public final java.lang.String toString() throws ;
Code:
0: aload_0
1: getfield #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
4: aload_0
5: getstatic #64; //Field m2:Ljava/lang/reflect/Method;
8: aconst_null
9: invokeinterface #28, 4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
14: checkcast #66; //class java/lang/String
17: areturn
18: athrow
19: astore_1
20: new #42; //class java/lang/reflect/UndeclaredThrowableException
23: dup
24: aload_1
25: invokespecial #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V
28: athrow
Exception table:
from to target type
0 18 18 Class java/lang/Error

0 18 18 Class java/lang/RuntimeException

0 18 19 Class java/lang/Throwable

static {} throws ;
Code:
0: ldc #70; //String java.lang.Object
2: invokestatic #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
5: ldc #77; //String equals
7: iconst_1
8: anewarray #72; //class java/lang/Class
11: dup
12: iconst_0
13: ldc #70; //String java.lang.Object
15: invokestatic #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
18: aastore
19: invokevirtual #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
22: putstatic #20; //Field m1:Ljava/lang/reflect/Method;
25: ldc #83; //String com.alibaba.test.performance.dynamicproxy.CountService
27: invokestatic #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
30: ldc #84; //String count
32: iconst_0
33: anewarray #72; //class java/lang/Class
36: invokevirtual #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
39: putstatic #50; //Field m3:Ljava/lang/reflect/Method;
42: ldc #70; //String java.lang.Object
44: invokestatic #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
47: ldc #85; //String hashCode
49: iconst_0
50: anewarray #72; //class java/lang/Class
53: invokevirtual #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
56: putstatic #59; //Field m0:Ljava/lang/reflect/Method;
59: ldc #70; //String java.lang.Object
61: invokestatic #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
64: ldc #86; //String toString
66: iconst_0
67: anewarray #72; //class java/lang/Class
70: invokevirtual #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
73: putstatic #64; //Field m2:Ljava/lang/reflect/Method;
76: return
77: astore_1
78: new #90; //class java/lang/NoSuchMethodError
81: dup
82: aload_1
83: invokevirtual #93; //Method java/lang/Throwable.getMessage:()Ljava/lang/String;
86: invokespecial #96; //Method java/lang/NoSuchMethodError."":(Ljava/lang/String;)V
89: athrow
90: astore_1
91: new #100; //class java/lang/NoClassDefFoundError
94: dup
95: aload_1
96: invokevirtual #93; //Method java/lang/Throwable.getMessage:()Ljava/lang/String;
99: invokespecial #101; //Method java/lang/NoClassDefFoundError."":(Ljava/lang/String;)V
102: athrow
Exception table:
from to target type
0 77 77 Class java/lang/NoSuchMethodException

0 77 90 Class java/lang/ClassNotFoundException

}

(2) CGLIB生成的字节码:

public class net.sf.cglib.core.MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7 extends net.sf.cglib.core.KeyFactory implements net.sf.cglib.core.MethodWrapper$MethodWrapperKey{
public net.sf.cglib.core.MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7();
Code:
0: aload_0
1: invokespecial #11; //Method net/sf/cglib/core/KeyFactory."":()V
4: return

public java.lang.Object newInstance(java.lang.String, java.lang.String[], java.lang.String);
Code:
0: new #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7
3: dup
4: aload_1
5: aload_2
6: aload_3
7: invokespecial #16; //Method “”:(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
10: areturn

public net.sf.cglib.core.MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7(java.lang.String, java.lang.String[], java.lang.String);
Code:
0: aload_0
1: invokespecial #11; //Method net/sf/cglib/core/KeyFactory.”":()V
4: aload_0
5: dup
6: aload_1
7: putfield #20; //Field FIELD_0:Ljava/lang/String;
10: dup
11: aload_2
12: putfield #24; //Field FIELD_1:[Ljava/lang/String;
15: dup
16: aload_3
17: putfield #27; //Field FIELD_2:Ljava/lang/String;
20: return

public int hashCode();
Code:
0: ldc #30; //int 938313161
2: aload_0
3: getfield #20; //Field FIELD_0:Ljava/lang/String;
6: swap
7: ldc #31; //int 362693231
9: imul
10: swap
11: dup
12: ifnull 21
15: invokevirtual #35; //Method java/lang/Object.hashCode:()I
18: goto 23
21: pop
22: iconst_0
23: iadd
24: aload_0
25: getfield #24; //Field FIELD_1:[Ljava/lang/String;
28: dup
29: ifnull 71
32: astore_1
33: iconst_0
34: istore_2
35: goto 62
38: aload_1
39: iload_2
40: aaload
41: swap
42: ldc #31; //int 362693231
44: imul
45: swap
46: dup
47: ifnull 56
50: invokevirtual #35; //Method java/lang/Object.hashCode:()I
53: goto 58
56: pop
57: iconst_0
58: iadd
59: iinc 2, 1
62: iload_2
63: aload_1
64: arraylength
65: if_icmplt 38
68: goto 72
71: pop
72: aload_0
73: getfield #27; //Field FIELD_2:Ljava/lang/String;
76: swap
77: ldc #31; //int 362693231
79: imul
80: swap
81: dup
82: ifnull 91
85: invokevirtual #35; //Method java/lang/Object.hashCode:()I
88: goto 93
91: pop
92: iconst_0
93: iadd
94: ireturn

public boolean equals(java.lang.Object);
Code:
0: aload_1
1: instanceof #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7
4: ifeq 181
7: aload_0
8: getfield #20; //Field FIELD_0:Ljava/lang/String;
11: aload_1
12: checkcast #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7
15: getfield #20; //Field FIELD_0:Ljava/lang/String;
18: dup2
19: ifnonnull 29
22: ifnonnull 35
25: pop2
26: goto 45
29: ifnull 35
32: goto 39
35: pop2
36: goto 181
39: invokevirtual #39; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z
42: ifeq 181
45: aload_0
46: getfield #24; //Field FIELD_1:[Ljava/lang/String;
49: aload_1
50: checkcast #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7
53: getfield #24; //Field FIELD_1:[Ljava/lang/String;
56: dup2
57: ifnonnull 67
60: ifnonnull 73
63: pop2
64: goto 141
67: ifnull 73
70: goto 77
73: pop2
74: goto 181
77: dup2
78: arraylength
79: swap
80: arraylength
81: if_icmpeq 88
84: pop2
85: goto 181
88: astore_2
89: astore_3
90: iconst_0
91: istore 4
93: goto 134
96: aload_2
97: iload 4
99: aaload
100: aload_3
101: iload 4
103: aaload
104: dup2
105: ifnonnull 115
108: ifnonnull 121
111: pop2
112: goto 131
115: ifnull 121
118: goto 125
121: pop2
122: goto 181
125: invokevirtual #39; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z
128: ifeq 181
131: iinc 4, 1
134: iload 4
136: aload_2
137: arraylength
138: if_icmplt 96
141: aload_0
142: getfield #27; //Field FIELD_2:Ljava/lang/String;
145: aload_1
146: checkcast #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7
149: getfield #27; //Field FIELD_2:Ljava/lang/String;
152: dup2
153: ifnonnull 163
156: ifnonnull 169
159: pop2
160: goto 179
163: ifnull 169
166: goto 173
169: pop2
170: goto 181
173: invokevirtual #39; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z
176: ifeq 181
179: iconst_1
180: ireturn
181: iconst_0
182: ireturn

public java.lang.String toString();
Code:
0: new #43; //class java/lang/StringBuffer
3: dup
4: invokespecial #44; //Method java/lang/StringBuffer.”":()V
7: aload_0
8: getfield #20; //Field FIELD_0:Ljava/lang/String;
11: dup
12: ifnull 24
15: invokevirtual #46; //Method java/lang/Object.toString:()Ljava/lang/String;
18: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
21: goto 30
24: pop
25: ldc #52; //String null
27: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
30: ldc #54; //String ,
32: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
35: aload_0
36: getfield #24; //Field FIELD_1:[Ljava/lang/String;
39: dup
40: ifnull 110
43: swap
44: ldc #56; //String {
46: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
49: swap
50: astore_1
51: iconst_0
52: istore_2
53: goto 86
56: aload_1
57: iload_2
58: aaload
59: dup
60: ifnull 72
63: invokevirtual #46; //Method java/lang/Object.toString:()Ljava/lang/String;
66: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
69: goto 78
72: pop
73: ldc #52; //String null
75: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
78: ldc #54; //String ,
80: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
83: iinc 2, 1
86: iload_2
87: aload_1
88: arraylength
89: if_icmplt 56
92: dup
93: dup
94: invokevirtual #59; //Method java/lang/StringBuffer.length:()I
97: iconst_2
98: isub
99: invokevirtual #63; //Method java/lang/StringBuffer.setLength:(I)V
102: ldc #65; //String }
104: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
107: goto 116
110: pop
111: ldc #52; //String null
113: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
116: ldc #54; //String ,
118: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
121: aload_0
122: getfield #27; //Field FIELD_2:Ljava/lang/String;
125: dup
126: ifnull 138
129: invokevirtual #46; //Method java/lang/Object.toString:()Ljava/lang/String;
132: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
135: goto 144
138: pop
139: ldc #52; //String null
141: invokevirtual #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
144: invokevirtual #66; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;
147: areturn

}

(3) JAVAASSIST动态代理接口生成的字节码:

public class com.alibaba.test.performance.dynamicproxy.CountService_$$_javassist_0 extends java.lang.Object implements com.alibaba.test.performance.dynamicproxy.CountService,javassist.util.proxy.ProxyObject{
public static javassist.util.proxy.MethodHandler default_interceptor;

public static javassist.util.proxy.MethodFilter _method_filter;

public com.alibaba.test.performance.dynamicproxy.CountService_$$_javassist_0();
Code:
0: aload_0
1: getstatic #19; //Field default_interceptor:Ljavassist/util/proxy/MethodHandler;
4: putfield #21; //Field handler:Ljavassist/util/proxy/MethodHandler;
7: getstatic #23; //Field default_interceptor:Ljavassist/util/proxy/MethodHandler;
10: ifnonnull 20
13: aload_0
14: getstatic #27; //Field javassist/util/proxy/RuntimeSupport.default_interceptor:Ljavassist/util/proxy/MethodHandler;
17: putfield #29; //Field handler:Ljavassist/util/proxy/MethodHandler;
20: aload_0
21: invokespecial #31; //Method java/lang/Object.”":()V
24: return

public final boolean _d0equals(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: invokespecial #38; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z
5: ireturn

public final boolean equals(java.lang.Object);
Code:
0: getstatic #42; //Field _methods_:[Ljava/lang/reflect/Method;
3: astore_2
4: aload_0
5: ldc #43; //String equals
7: ldc #44; //String _d0equals
9: iconst_0
10: ldc #45; //String (Ljava/lang/Object;)Z
12: aload_2
13: invokestatic #49; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V
16: aload_0
17: getfield #51; //Field handler:Ljavassist/util/proxy/MethodHandler;
20: aload_0
21: aload_2
22: iconst_0
23: aaload
24: aload_2
25: iconst_1
26: aaload
27: iconst_1
28: anewarray #52; //class java/lang/Object
31: dup
32: iconst_0
33: aload_1
34: aastore
35: invokeinterface #58, 5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
40: checkcast #60; //class java/lang/Boolean
43: invokevirtual #64; //Method java/lang/Boolean.booleanValue:()Z
46: ireturn

public final java.lang.Object _d1clone() throws java.lang.CloneNotSupportedException;
Code:
0: aload_0
1: invokespecial #72; //Method java/lang/Object.clone:()Ljava/lang/Object;
4: areturn

protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException;
Code:
0: getstatic #74; //Field _methods_:[Ljava/lang/reflect/Method;
3: astore_1
4: aload_0
5: ldc #75; //String clone
7: ldc #76; //String _d1clone
9: iconst_2
10: ldc #77; //String ()Ljava/lang/Object;
12: aload_1
13: invokestatic #79; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V
16: aload_0
17: getfield #81; //Field handler:Ljavassist/util/proxy/MethodHandler;
20: aload_0
21: aload_1
22: iconst_2
23: aaload
24: aload_1
25: iconst_3
26: aaload
27: iconst_0
28: anewarray #52; //class java/lang/Object
31: invokeinterface #83, 5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
36: checkcast #4; //class java/lang/Object
39: areturn

public final int _d2hashCode();
Code:
0: aload_0
1: invokespecial #88; //Method java/lang/Object.hashCode:()I
4: ireturn

public final int hashCode();
Code:
0: getstatic #90; //Field _methods_:[Ljava/lang/reflect/Method;
3: astore_1
4: aload_0
5: ldc #91; //String hashCode
7: ldc #92; //String _d2hashCode
9: iconst_4
10: ldc #93; //String ()I
12: aload_1
13: invokestatic #95; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V
16: aload_0
17: getfield #97; //Field handler:Ljavassist/util/proxy/MethodHandler;
20: aload_0
21: aload_1
22: iconst_4
23: aaload
24: aload_1
25: iconst_5
26: aaload
27: iconst_0
28: anewarray #52; //class java/lang/Object
31: invokeinterface #99, 5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
36: checkcast #101; //class java/lang/Integer
39: invokevirtual #104; //Method java/lang/Integer.intValue:()I
42: ireturn

public final int count();
Code:
0: getstatic #107; //Field _methods_:[Ljava/lang/reflect/Method;
3: astore_1
4: aload_0
5: ldc #108; //String count
7: aconst_null
8: bipush 6
10: ldc #109; //String ()I
12: aload_1
13: invokestatic #111; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V
16: aload_0
17: getfield #113; //Field handler:Ljavassist/util/proxy/MethodHandler;
20: aload_0
21: aload_1
22: bipush 6
24: aaload
25: aload_1
26: bipush 7
28: aaload
29: iconst_0
30: anewarray #52; //class java/lang/Object
33: invokeinterface #115, 5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
38: checkcast #101; //class java/lang/Integer
41: invokevirtual #117; //Method java/lang/Integer.intValue:()I
44: ireturn

public final void _d4finalize() throws java.lang.Throwable;
Code:
0: aload_0
1: invokespecial #123; //Method java/lang/Object.finalize:()V
4: return

protected final void finalize() throws java.lang.Throwable;
Code:
0: getstatic #125; //Field _methods_:[Ljava/lang/reflect/Method;
3: astore_1
4: aload_0
5: ldc #126; //String finalize
7: ldc #127; //String _d4finalize
9: bipush 8
11: ldc #128; //String ()V
13: aload_1
14: invokestatic #130; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V
17: aload_0
18: getfield #132; //Field handler:Ljavassist/util/proxy/MethodHandler;
21: aload_0
22: aload_1
23: bipush 8
25: aaload
26: aload_1
27: bipush 9
29: aaload
30: iconst_0
31: anewarray #52; //class java/lang/Object
34: invokeinterface #134, 5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
39: pop
40: return

public final java.lang.String _d5toString();
Code:
0: aload_0
1: invokespecial #139; //Method java/lang/Object.toString:()Ljava/lang/String;
4: areturn

public final java.lang.String toString();
Code:
0: getstatic #141; //Field _methods_:[Ljava/lang/reflect/Method;
3: astore_1
4: aload_0
5: ldc #142; //String toString
7: ldc #143; //String _d5toString
9: bipush 10
11: ldc #144; //String ()Ljava/lang/String;
13: aload_1
14: invokestatic #146; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V
17: aload_0
18: getfield #148; //Field handler:Ljavassist/util/proxy/MethodHandler;
21: aload_0
22: aload_1
23: bipush 10
25: aaload
26: aload_1
27: bipush 11
29: aaload
30: iconst_0
31: anewarray #52; //class java/lang/Object
34: invokeinterface #150, 5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
39: checkcast #152; //class java/lang/String
42: areturn

static {};
Code:
0: bipush 12
2: anewarray #155; //class java/lang/reflect/Method
5: putstatic #157; //Field _methods_:[Ljava/lang/reflect/Method;
8: return

public void setHandler(javassist.util.proxy.MethodHandler);
Code:
0: aload_0
1: aload_1
2: putfield #161; //Field handler:Ljavassist/util/proxy/MethodHandler;
5: return

java.lang.Object writeReplace() throws java.io.ObjectStreamException;
Code:
0: aload_0
1: invokestatic #168; //Method javassist/util/proxy/RuntimeSupport.makeSerializedProxy:(Ljava/lang/Object;)Ljavassist/util/proxy/SerializedProxy;
4: areturn

}

(5) JAVAASSIST拼接源码生成的字节码:

public class com.alibaba.test.performance.dynamicproxy.CountServiceJavaassistProxy extends java.lang.Object implements com.alibaba.test.performance.dynamicproxy.CountService{
public com.alibaba.test.performance.dynamicproxy.CountService delegate;

public com.alibaba.test.performance.dynamicproxy.CountServiceJavaassistProxy();
Code:
0: aload_0
1: invokespecial #12; //Method java/lang/Object.”":()V
4: return

public int count();
Code:
0: aload_0
1: getfield #19; //Field delegate:Lcom/alibaba/test/performance/dynamicproxy/CountService;
4: invokeinterface #21, 1; //InterfaceMethod com/alibaba/test/performance/dynamicproxy/CountService.count:()I
9: ireturn

}

(6) 用ASM自行生成的字节码:

public class com.alibaba.test.performance.dynamicproxy.CountServiceAsmProxy extends java.lang.Object implements com.alibaba.test.performance.dynamicproxy.CountService{
public com.alibaba.test.performance.dynamicproxy.CountService delegate;

public com.alibaba.test.performance.dynamicproxy.CountServiceAsmProxy();
Code:
0: aload_0
1: invokespecial #10; //Method java/lang/Object.”":()V
4: return

public int count();
Code:
0: aload_0
1: getfield #16; //Field delegate:Lcom/alibaba/test/performance/dynamicproxy/CountService;
4: invokeinterface #18, 1; //InterfaceMethod com/alibaba/test/performance/dynamicproxy/CountService.count:()I
9: ireturn

}

分享到:
评论

相关推荐

    Adroid动态加载Apk-插件化技术框架(动态代理方案)源码

    Android动态加载Apk-插件化技术(动态代理方案) 一. 什么是插件化 1. 主App(宿主App)加载插件apk的实现 2. 每个业务组件模块形成一个独立的Apk, 然后通过主App动态加载部署业务组件模块Apk的一种方案 二.插件化的...

    局域网中代理服务器、路由器的配置方案

    局域网中代理服务器 路由器的配置方案 网络技术的飞速发展 使企事业单位局域网接入INTERNET共享资源的方式越来越多 就大多数而言 DDN专线以其性能稳定 扩充性好的优势成为普遍采用的方式 DDN方式的连接在硬件的需求...

    java8stream源码-daydayup:天天向上

    java8 stream 源码 Java各种开源库积累 好好学习,天天向上。 演示内容 1)src/main/java org.xpen.audio 播放各种声音格式ogg,mp3,ape,flac org.xpen.chess.puzzle8 ...动态代理方案性能对比,比较了J

    提升Ruby on Rails性能的几个解决方案

    简介 Ruby On Rails 框架自它提出之日起就受到广泛关注,在“不要重复自己”,“约定优于配置”等思想的指导下,Rails 带给 Web 开发者的是极高的开发效率。 ActiveRecord 的灵活让你再也不用配置繁琐的 Hibernate ...

    安卓推送方案及比较

    经常有朋友困扰于Android上面实现推送的技术,希望知道各种方案的优缺点、性能、开发难度等,于是特意写了这篇文章。 方案一: Google官方的服务: 但,通过对比研究发现C2DM机制存在以下缺点: 1)GCM要求Android...

    论文研究-6LoWPAN嵌套移动网络路由优化方案.pdf

    提出一种6LoWPAN嵌套移动网络路由优化方案,在此方案中,6LoWPAN...从理论和仿真两个角度对所提出的路由优化方案的路由优化开销、路由延迟及路由代价等性能参数进行了比较分析,分析结果验证了本方案的有效性和高效性。

    HTTPS 代理-SNI Proxy-WebSocket-Java

    网上搜了一圈,也没找到简单的解决方案。用NGINX折腾了一天,但搭出来的系统很不稳定。干脆用java自己写了个小程序,性能当然和squid、nginx之类的没法比,还好我们的系统负荷不是很重,运行了一个星期基本没问题。 ...

    论文研究-一种MANET地址自动配置方案.pdf

    提出一种MANET地址自动配置方案, 给出了...对MANETConf、Prime DHCP以及本方案的性能参数进行了比较分析, 性能参数包括地址配置代价及地址配置延迟时间, 分析结果验证了本方案的地址配置代价更低, 地址配置延迟更短。

    论文研究-关于CORBA与移动代理结合用于网络管理的研究.pdf

    CORBA和移动代理是目前在分布式网络管理领域中应用得比较广泛的两种技术。在实际应用与研究领域中,它们都在不同的方面呈现出了各自的优势。但是,这两种技术又都存在着不同程度的缺陷。为了弥补移动代理和CORBA的...

    基于SM2的代理保护代理签名的设计与实现

    基于国产密码算法 SM2 数字签名标准,设计了一种代理保护代理签名方案。...最后,利用C语言及Polarssl库对该方案进行了实现,并与SM2数字签名进行了性能比较。分析表明,该算法在性能上具有较好的可用性。

    论文研究-)门限代理签名方案.pdf

    利用节点感知数据的空间相似性,提出了节点故障诊断的算法,通过对邻节点所感知的传感数据进行比较,从而确定检测节点的状态,并将测试状态向网络中其他相邻节点进行扩散。该算法对实现故障节点的检测具有较好的性能...

    论文研究-前向安全的代理盲签名方案.pdf

    基于移动节点的能量级别,采取不同的转发概率,提出了一种Ad Hoc网络基于概率的路由协议——PBR,并与AODV协议进行了性能比较,仿真结果显示,PBR明显改善了系统的能量消耗,延长了网络的存活时间,并且具有较优的可...

    WProxy.rar

    WProxy 绿色免费版 WProxy是一款运行在windows系统上的代理服务器软件,可以给局域网的其他电脑提供代理上网服务,支持HTTP、...支持高并发处理,性能和squid代理比较毫不逊色,具体性能请参考“性能”。 终身免费。

    XX系统方案设计.doc

    解决方案 1 企业级整体解决方案 XX申请管理系统采用当今比较流行和技术比较先进的Microsoft.NET体系作为软件开 发平台和运行平台,以ASP.NET作为主流开发工具和软件运行的主要表现形式,采用当今 软件主要表现形式...

    SQLServer安全及性能优化

    数据库的性能优化主要有两个方面:减少查询比较次数、减少资源的征用。 使用工具Sql Server Profiler优化数据库的性能,减少资源的征用 SqlServer Profiler的功能 Sql Server Profiler的用法  定义跟踪  ...

    服务器故障应急响应方案.docx

    服务器故障应急响应方案 精品资料 服务器故障应急响应方案全文共8页,当前为第1页。服务器故障应急响应方案全文共8页,当前为第1页。 服务器故障应急响应方案全文共8页,当前为第1页。 服务器故障应急响应方案全文共...

    论文研究-基于PMIPv6的域间切换管理方法及性能分析.pdf

    针对代理移动IPv6(PMIPv6)中域间切换时延较大的问题,提出了一种基于PMIPv6的域间切换管理方案。新方案通过在PMIPv6域间发送PBU绑定更新消息,使得切换目标PMIPv6域提前知道移动节点(MN)的家乡网络前缀,避免了...

    构建最高可用Oracle数据库系统 Oracle 11gR2 RAC管理、维护与性能优化

    10.7.6 CHM与OSWatcher对比 10.8本章小结 第11章 最高可用性 11.1最高可用性架构 11.1.1 Data Guard优势 11.1.2客户端Failover 11.1.3 Data Guard配置 11.1.4 Standby数据库 11.1.5 Data Guard保护模式 ...

Global site tag (gtag.js) - Google Analytics