动态代理方案性能对比(转载)
原文 http://javatar.iteye.com/blog/814426
转于自己在公司的Blog:
http://pt.alibaba-inc.com/wp/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
- }