20

While analyzing a heap dump using jhat I have observed many instances of DelegatingClassLoader created although they were not called explicitly in code. I expect this to be some sort of reflection optimization mechanism. Does anybody know the details?

Eugen
  • 2,292
  • 3
  • 29
  • 43

2 Answers2

20

Yes, it is probably a reflection optimisation.

On the Sun JVM, reflective access to properties and methods is initially performed by calling through JNI into the JVM implementation. If the JVM notices that a method or field is being accessed by reflection a lot, it will generate bytecode to do the same thing -- a mechanism that it calls "inflation". This has an initial speed hit, but after that runs about 20 times faster. A big win if you do a lot of reflection.

That bytecode lives in classes created by DelegatingClassLoader instances. Keep an eye on it: those classes can put pressure on the permgen space and cause the dreaded "java.lang.OutOfMemoryError: PermGen space" failures. If it is a problem, you can turn inflation off by setting the system property sun.reflect.inflationThreshold to 0 (zero).

Nat
  • 9,820
  • 3
  • 31
  • 33
  • Warning, the property works on Oracle/OpenJDK and IBM JDK, however on IBM it turns the inflation on, on Sun it immediatelly inflates (tried this using -verbose:class which returns in DelegatedClassLoaders beeing instantiated, as the code for IBM is not available). On both the default value is 15, I would think about setting it to 1000 or something to reduce inflations but still benefit from speedup. – eckes Dec 08 '13 at 04:10
  • No field, only method applies this optimization. – h2o2 Apr 13 '22 at 09:48
3

I don't see (at least for Hotspot), when looking at code

http://javasourcecode.org/html/open-source/jdk/jdk-6u23/sun/reflect/ReflectionFactory.java.html

and

http://javasourcecode.org/html/open-source/jdk/jdk-6u23/sun/reflect/NativeMethodAccessorImpl.java.html

that a setting of zero will turn off the feature. Seems to me only a large value for sun.reflect.inflationThreshold will do the job.

C. Allain
  • 31
  • 1
  • IBM behaves differently, it will turn it off with 0 or 1. (Not sure if it does anything different for 0 or 1, but with both I dont see a DelegatingClassLoader be loaded). – eckes Dec 08 '13 at 04:11