zoukankan      html  css  js  c++  java
  • 动态代理方案性能对比

    本文转载自动态代理方案性能对比

    导语

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

    测试结果

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

    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
    ----------------
    

    服务器测试结果

    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);
    		}
    	}
    }
    

    字节码对比

    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
    }
    

    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
    }
    

    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
    }
    

    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
    }
    

    用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
    }
    
  • 相关阅读:
    10个用jQuery实现图片幻灯片/画廊效果和源码
    老赵面试题参考答案(二)
    C#的显式接口和隐式接口
    老赵面试题参考答案(三)
    C#中的参数传递:值类型(value type)和引用类型(reference type)
    word转换成html的方法
    老赵面试题参考答案(四)
    五个Metro UI 风格的网页设计
    老赵面试题参考答案(六)
    概要设计怎么写?
  • 原文地址:https://www.cnblogs.com/yungyu16/p/13163140.html
Copyright © 2011-2022 走看看