I recently came across this interesting term and searched on Net to know more about it. However the info I found is sketchy. Could someone pl. give me a somewhat detailed explanation of what this is and why is this useful?
我最近发现了这个有趣的术语,并在网上搜索了更多关于它的信息。但是我发现的信息是粗略的。能不能给我一个详细的解释这个是什么,为什么这个有用?
From the info I found, it looks like this mechanism makes reflective method execution faster, at the expense of creating a lot of dynamic classes and hogging perm gen memory area, but I'm not sure about it.
从我发现的信息来看,这种机制使反射方法执行速度更快,代价是创建大量动态类并占用perm gen内存区域,但我不确定。
3 个解决方案
#1
13
Did some source code digging and coding myself to figure this out, and here's what I've found out:
我自己做了一些源代码挖掘和编码来解决这个问题,以下是我发现的:
Java's 'Method' class has a member variable 'methodAccessor' of type 'MethodAccessor' which is an interface with a method 'invoke', similar to Method's invoke. Methods's invoke delegates to methodAccessor's invoke.
Java的“方法”类具有“methodAccessor”类型的成员变量“methodAccessor”,“methodAccessor”是一个带有方法“调用”的接口,类似于方法的调用。方法的调用委托给methodAccessor的调用。
If inflation is enabled (noInflation is false) this accessor points to an implementation which uses JNI to run this Java method (I think using api's like GetObjectClass, GetMethodID and Call*Method). This is like duel dispatching, and execution with JNI is slow due to this and other reasons. ( What makes JNI calls slow? )
如果启用了通胀(noInflation是false),这个访问器指向一个实现,该实现使用JNI来运行这个Java方法(我认为使用api,比如GetObjectClass、getmethod did和Call*方法)。这就像决斗调度,由于这个和其他原因,与JNI的执行速度很慢。(JNI为什么说慢?)
After 15 executions of a method through reflection ('15' is default and can be changed) and with noInflation false, the JNI based accessor creates a class on the fly (the name is dynamically generated, e.g. say 'GeneratedMethodAccessor1') which also has the invoke method. Now, within this 'invoke' method, it casts the first 'obj' argument to its corresponding class, and then calls the target method on it. It then creates an instance of this class, and changes the methodAccessor settings such that every execution of the method henceforth is delegated to this instance instead of JNI accessor. This is called inflation.
通过反射(“15”是默认值,可以更改)和noInflation false之后,执行了15次的方法后,基于JNI的访问器创建了一个动态的类(名称是动态生成的,例如“GeneratedMethodAccessor1”),它也有invoke方法。现在,在这个“调用”方法中,它将第一个“obj”参数转换为相应的类,然后对其调用目标方法。然后,它创建该类的一个实例,并更改methodAccessor设置,以便从此以后方法的每个执行都被委托给这个实例,而不是JNI accessor。这被称为通货膨胀。
Because this instance is of a Java class which delegates to a Java object, the delegation henceforth is a normal Java delegation. It never goes to JNI and hence saves that overhead, plus JITC can perform other optimization on it due to which it becomes efficient.
因为这个实例是一个Java类,它将委托给一个Java对象,所以从此以后委托就是一个普通的Java委托。它永远不会转到JNI,因此节省了开销,加上JITC可以对它执行其他优化,从而使它变得高效。
The downside is, if a lot of methods are inflated in this manner, their classes occupy permgen space and can possibly cause out of memory error.
缺点是,如果许多方法以这种方式膨胀,它们的类会占用permgen空间,并且可能导致内存错误。
For details, see:
更多细节,请参阅:
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/sun/reflect/ReflectionFactory.java
http://java.sun.com/docs/books/jni/html/fldmeth.html
http://java.sun.com/docs/books/jni/html/fldmeth.html
http://anshuiitk.blogspot.com/2010/11/excessive-full-garbage-collection.html
http://anshuiitk.blogspot.com/2010/11/excessive-full-garbage-collection.html
#2
2
Java Inflation is optimization of method calls made through Java Reflection API. It delegates infrequent method calls to cheap, immediately available but slow Java Native Interface and frequent method calls to fast but expensive, runtime generated method accessor.
Java通胀是通过Java反射API进行的方法调用的优化。它将不频繁的方法调用委托给廉价的、立即可用的但缓慢的Java本机接口和频繁的方法调用,以快速但昂贵的运行时生成的方法访问器。
#3
1
Not sure though but read this somewhere Inflation means that for the first few runs (default 15) of a reflected method/constructor (from now on, any reference to methods applies to constructors too), it does so via JNI; the next time after that, it assembles a class file on the fly, and loads it. At that point, full JITting applies, and further calls to that reflected method has the same performance as directly calling that method
虽然不确定,但是在某处读一下,Inflation意味着对于反射的方法/构造函数的前几次运行(默认值为15)(从现在开始,对方法的任何引用也适用于构造函数),它是通过JNI进行的;下一次,它会动态地组装一个类文件,并加载它。此时,应用完整的jowing,对反射方法的进一步调用具有与直接调用该方法相同的性能
#1
13
Did some source code digging and coding myself to figure this out, and here's what I've found out:
我自己做了一些源代码挖掘和编码来解决这个问题,以下是我发现的:
Java's 'Method' class has a member variable 'methodAccessor' of type 'MethodAccessor' which is an interface with a method 'invoke', similar to Method's invoke. Methods's invoke delegates to methodAccessor's invoke.
Java的“方法”类具有“methodAccessor”类型的成员变量“methodAccessor”,“methodAccessor”是一个带有方法“调用”的接口,类似于方法的调用。方法的调用委托给methodAccessor的调用。
If inflation is enabled (noInflation is false) this accessor points to an implementation which uses JNI to run this Java method (I think using api's like GetObjectClass, GetMethodID and Call*Method). This is like duel dispatching, and execution with JNI is slow due to this and other reasons. ( What makes JNI calls slow? )
如果启用了通胀(noInflation是false),这个访问器指向一个实现,该实现使用JNI来运行这个Java方法(我认为使用api,比如GetObjectClass、getmethod did和Call*方法)。这就像决斗调度,由于这个和其他原因,与JNI的执行速度很慢。(JNI为什么说慢?)
After 15 executions of a method through reflection ('15' is default and can be changed) and with noInflation false, the JNI based accessor creates a class on the fly (the name is dynamically generated, e.g. say 'GeneratedMethodAccessor1') which also has the invoke method. Now, within this 'invoke' method, it casts the first 'obj' argument to its corresponding class, and then calls the target method on it. It then creates an instance of this class, and changes the methodAccessor settings such that every execution of the method henceforth is delegated to this instance instead of JNI accessor. This is called inflation.
通过反射(“15”是默认值,可以更改)和noInflation false之后,执行了15次的方法后,基于JNI的访问器创建了一个动态的类(名称是动态生成的,例如“GeneratedMethodAccessor1”),它也有invoke方法。现在,在这个“调用”方法中,它将第一个“obj”参数转换为相应的类,然后对其调用目标方法。然后,它创建该类的一个实例,并更改methodAccessor设置,以便从此以后方法的每个执行都被委托给这个实例,而不是JNI accessor。这被称为通货膨胀。
Because this instance is of a Java class which delegates to a Java object, the delegation henceforth is a normal Java delegation. It never goes to JNI and hence saves that overhead, plus JITC can perform other optimization on it due to which it becomes efficient.
因为这个实例是一个Java类,它将委托给一个Java对象,所以从此以后委托就是一个普通的Java委托。它永远不会转到JNI,因此节省了开销,加上JITC可以对它执行其他优化,从而使它变得高效。
The downside is, if a lot of methods are inflated in this manner, their classes occupy permgen space and can possibly cause out of memory error.
缺点是,如果许多方法以这种方式膨胀,它们的类会占用permgen空间,并且可能导致内存错误。
For details, see:
更多细节,请参阅:
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/sun/reflect/ReflectionFactory.java
http://java.sun.com/docs/books/jni/html/fldmeth.html
http://java.sun.com/docs/books/jni/html/fldmeth.html
http://anshuiitk.blogspot.com/2010/11/excessive-full-garbage-collection.html
http://anshuiitk.blogspot.com/2010/11/excessive-full-garbage-collection.html
#2
2
Java Inflation is optimization of method calls made through Java Reflection API. It delegates infrequent method calls to cheap, immediately available but slow Java Native Interface and frequent method calls to fast but expensive, runtime generated method accessor.
Java通胀是通过Java反射API进行的方法调用的优化。它将不频繁的方法调用委托给廉价的、立即可用的但缓慢的Java本机接口和频繁的方法调用,以快速但昂贵的运行时生成的方法访问器。
#3
1
Not sure though but read this somewhere Inflation means that for the first few runs (default 15) of a reflected method/constructor (from now on, any reference to methods applies to constructors too), it does so via JNI; the next time after that, it assembles a class file on the fly, and loads it. At that point, full JITting applies, and further calls to that reflected method has the same performance as directly calling that method
虽然不确定,但是在某处读一下,Inflation意味着对于反射的方法/构造函数的前几次运行(默认值为15)(从现在开始,对方法的任何引用也适用于构造函数),它是通过JNI进行的;下一次,它会动态地组装一个类文件,并加载它。此时,应用完整的jowing,对反射方法的进一步调用具有与直接调用该方法相同的性能