Skip to content

ClassLoading

Sam Berlin edited this page Aug 5, 2015 · 5 revisions

Motivation for and consequences of generating classes in Guice

Class Loading

Guice performs code generation and class loading. We use this stuff for faster reflection, method interceptors, and to proxy circular dependencies.

When loading classes, we need to be careful of:

  • Memory leaks. Generated classes need to be garbage collected in long-lived applications. Once an injector and any instances it created can be garbage collected, the corresponding generated classes should be collectable.
  • Visibility. Containers like OSGi use class loader boundaries to enforce modularity at runtime.

For each generated class, there's multiple class loaders involved:

  • The target class's class loader. Every generated class services exactly one user-supplied class. This class loader must be used to access members with private and package visibility.
  • Guice's class loader.
  • Our bridge class loader. This is a child of the target class's loader. It selectively delegates to either the target class's loader (for user classes) or the Guice class loader (for internal classes that are used by the generated classes). This class loader that owns the classes generated by Guice.

The Bridge ClassLoader

Guice uses its bridge class loader unless:

  • A package-private method or constructor is being intercepted
  • A method in a package-private class is being intercepted
  • Any parameters or return types of the method or constructor being intercepted are package-private
  • The target class was loaded by the system class loader
  • It is disabled

Only classes loaded by the bridge class loader will work in an OSGi environment.

Disabling Guice's Bridge ClassLoader

Setting the system property guice_custom_class_loading to OFF will cause Guice to use the target class's classloader for all generated classes. Guice's bridge classloader will not be used.

Generated Classes and Memory Leaks

Classes can only be garbage collected when all of their instances and the originating classloader are no longer referenced. The bridge class loader is intended to allow generated classes to be garbage collected as quickly as possible.

To minimize the amount of PermGen memory used by Guice-generated classes, avoid intercepting package-private methods.

Clone this wiki locally