从我发现的信息中,看起来这种机制使得反射方法执行更快,牺牲了创建大量的动态类和占用永久内存区域,但我不确定.@H_404_3@
解决方法
Java的’Method’类有一个“MethodAccessor”类型的成员变量’methodAccessor’,它是一个方法’invoke’的接口,类似于Method的调用.方法调用方法来访问methodAccessor的调用.@H_404_3@
如果启用通货膨胀(noInflation为false),则该访问器指向使用JNI运行此Java方法的实现(我认为使用api的GetObjectClass,GetMethodID和Call * Method).这就像决斗派遣,由于这个原因和其他原因,JNI的执行速度很慢.
(What makes JNI calls slow?)@H_404_3@
在15次执行方法通过反射(’15’是默认并且可以改变)和noInflation false之后,基于JNI的访问器即时创建一个类(名称是动态生成的,例如说’GeneratedMethodAccessor1′),它也有调用方法.现在,在这个’invoke’方法中,它将第一个’obj’参数转换成其对应的类,然后调用它的目标方法.然后,它创建此类的实例,并更改methodAccessor设置,以便以后将该方法的每次执行委托给此实例而不是JNI访问器.这就是所谓的通货膨胀.@H_404_3@
因为这个实例是一个委托给Java对象的Java类,所以后来的委托是一个普通的Java委托.它永远不会去JNI,因此节省了开销,加上JITC可以对其进行其他优化,因为它变得高效.@H_404_3@
缺点是,如果以这种方式充斥了很多方法,它们的类占用多余空间,并且可能导致内存不足错误.@H_404_3@
详情请参阅:@H_404_3@
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/sun/reflect/ReflectionFactory.java@H_404_3@
http://java.sun.com/docs/books/jni/html/fldmeth.html@H_404_3@
http://anshuiitk.blogspot.com/2010/11/excessive-full-garbage-collection.html@H_404_3@