public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
public final class Method extends Executable { public Object invoke(Object obj, Object... args) throws ... { ... // 权限检查 MethodAccessor ma = methodAccessor; if (ma == null) { ma = acquireMethodAccessor(); } // 委派给MethodAccessor来处理 return ma.invoke(obj, args); } } public interface MethodAccessor { Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException; }
每个Method实例的 第一次反射调用 都会生成一个 委派实现 ,它 所委派的具体实现 便是一个 本地实现
public class V0 { public static void target(int i) { new Exception("#" + i).printStackTrace(); } public static void main(String[] args) throws Exception { Class<?> klass = Class.forName(V0.class.getName()); Method method = klass.getMethod("target", int.class); method.invoke(null, 0); } }
// 本地实现 // Method.invoke -> DelegatingMethodAccessorImpl.invoke // -> NativeMethodAccessorImpl.invoke -> NativeMethodAccessorImpl.invoke0 java.lang.Exception: #0 at me.zhongmingmao.basic.reflect.V0.target(V0.java:7) -- Java at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) -- C++ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) -- Java at me.zhongmingmao.basic.reflect.V0.main(V0.java:13)
// 动态实现的伪代码 package jdk.internal.reflect; public class GeneratedMethodAccessor1 extends ... { @Overrides public Object invoke(Object obj, Object[] args) throws ... { V0.target((int) args[0]); return null; } }
// -verbose:class public class V1 { public static void target(int i) { new Exception("#" + i).printStackTrace(); } public static void main(String[] args) throws Exception { Class<?> klass = Class.forName(V1.class.getName()); Method method = klass.getMethod("target", int.class); for (int i = 0; i < 20; i++) { method.invoke(null, i); } } }
// 第15次反射调用时,触发了动态实现的生成,JVM额外加载其他类 java.lang.Exception: #14 at me.zhongmingmao.basic.reflect.V1.target(V1.java:7) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at me.zhongmingmao.basic.reflect.V1.main(V1.java:14) ... // 加载自动生成的字节码 [Loaded sun.reflect.GeneratedMethodAccessor1 from __JVM_DefineClass__] java.lang.Exception: #15 at me.zhongmingmao.basic.reflect.V1.target(V1.java:7) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at me.zhongmingmao.basic.reflect.V1.main(V1.java:14) // 切换至刚刚生成的动态实现 java.lang.Exception: #16 at me.zhongmingmao.basic.reflect.V1.target(V1.java:7) at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at me.zhongmingmao.basic.reflect.V1.main(V1.java:14)
public class V2 { public static void target(int i) { } private static void directCall() { long current = System.currentTimeMillis(); for (int i = 1; i <= 2_000_000_000; i++) { if (i % 100_000_000 == 0) { long temp = System.currentTimeMillis(); System.out.println(temp - current); current = temp; } V2.target(128); } } public static void main(String[] args) { directCall(); } }
// -XX:+PrintGC public class V3 { public static void target(int i) { } private static void reflectCall() throws Exception { Class<?> klass = Class.forName("me.zhongmingmao.basic.reflect.V3"); Method method = klass.getMethod("target", int.class); long current = System.currentTimeMillis(); for (int i = 1; i <= 2_000_000_000; i++) { if (i % 100_000_000 == 0) { long temp = System.currentTimeMillis(); System.out.println(temp - current); current = temp; } method.invoke(null, 128); } } public static void main(String[] args) throws Exception { reflectCall(); } }
峰值性能:457.4ms,为基准耗时的4.1倍
63: aload_1 // 加载Method对象 64: aconst_null // 静态方法,反射调用的第一个参数为null 65: iconst_1 66: anewarray // 生成一个长度为1的Object数组 69: dup 70: iconst_0 71: sipush 128 74: invokestatic Integer.valueOf // 将128自动装箱成Integer 77: aastore // 存入Object数组 78: invokevirtual Method.invoke // 反射调用
反射调用前的两个动作
// -XX:+PrintGC public class V4 { public static void target(int i) { } public static void main(String[] args) throws Exception { Class<?> klass = Class.forName("me.zhongmingmao.basic.reflect.V4"); Method method = klass.getMethod("target", int.class); // 在循环外构造参数数组 Object[] arg = new Object[1]; arg[0] = 128; long current = System.currentTimeMillis(); for (int i = 1; i <= 2_000_000_000; i++) { if (i % 100_000_000 == 0) { long temp = System.currentTimeMillis(); System.out.println(temp - current); current = temp; } method.invoke(null, arg); } } }
80: aload_2 // 加载Method对象 81: aconst_null // 静态方法,反射调用的第一个参数为null 82: aload_3 83: invokevirtual Method.invoke // 反射调用,无anewarray指令
// -Djava.lang.Integer.IntegerCache.high=128 // -Dsun.reflect.noInflation=true public class V5 { public static void target(int i) { } public static void main(String[] args) throws Exception { Class<?> klass = Class.forName("me.zhongmingmao.basic.reflect.V5"); Method method = klass.getMethod("target", int.class); // 关闭权限检查 method.setAccessible(true); long current = System.currentTimeMillis(); for (int i = 1; i <= 2_000_000_000; i++) { if (i % 100_000_000 == 0) { long temp = System.currentTimeMillis(); System.out.println(temp - current); current = temp; } method.invoke(null, 128); } } }
峰值性能:186.2ms,为基准耗时的1.7倍
public class V6 { public static void target(int i) { } public static void target1(int i) { } public static void target2(int i) { } public static void polluteProfile() throws Exception { // 误扰Method.invoke()的类型profile Method method1 = V6.class.getMethod("target1", int.class); Method method2 = V6.class.getMethod("target2", int.class); for (int i = 0; i < 2000; i++) { method1.invoke(null, 0); method2.invoke(null, 0); } } public static void main(String[] args) throws Exception { Class<?> klass = Class.forName("me.zhongmingmao.basic.reflect.V6"); Method method = klass.getMethod("target", int.class); // 关闭权限检查 method.setAccessible(true); polluteProfile(); long current = System.currentTimeMillis(); for (int i = 1; i <= 2_000_000_000; i++) { if (i % 100_000_000 == 0) { long temp = System.currentTimeMillis(); System.out.println(temp - current); current = temp; } method.invoke(null, 128); } } }
转载请注明出处:http://zhongmingmao.me/2018/12/20/jvm-basic-reflection/
访问原文「JVM基础 -- 反射原理」获取最佳阅读体验并参与讨论