Reflection - a memory viewpoint

Reflection in Java is primarily used to retrieve class information during run time. But its also a way to generate classes. This happens through the "accessor" . When using reflection, the JVM connects to the methods of a reflecting object to the obj/class being reflected on. The "accessor" can be of two types

JNI

Bytecode

JNI accessor is a native accessor which requires very little setupBytecode accessor is the "dynamic class generation" aspect of reflection

JNI accessor is a fast to setup - slow to run this is because switching from Java context to Native context is always time consumingBytecode accessor is slow to setup - fast to run slow to setup because it needs building a class and loading it through a new classloader - but faster later on as you can have JIT optimize the class for you

Initially, the JVM uses JNI accessor for reflection. After a "threshold" , these accessors are promoted to bytecode accessors. This is called INFLATION. Excessive Reflection has a drawback : it could lead to lot of bytecode accessors being created which inturn means lot of accessor classes and classloaders - both of which take up native memory to a large extent. If your app is seen to be creating lot of Generated*Accessor classes or sun.reflect.DelegatingClassloaders, then you should be looking at tuning reflection and inflation.

TUNING:The default threshold for inflation for IBM Java 5.0 is 15 and can be controlled through the system property -Dsun.reflect.inflationThreshold=NIf N is 0 or less, then the accessors will never be inflated.

Disabling inflation:-Dsun.reflect.noInflation=true disables inflation entirely but it also means that bytecode accessors are used by default. This could lead to a high native memory footprint due to reasons mentioned above.

Make sure you read this excellent dW article on Native Memory http://www.ibm.com/developerworks/java/library/j-nativememory-linux/