I digged into the problem and these are my findings: - ByteCodeGen always creates a new fast class generator for every type and member: https://github.com/google/guice/blob/master/core/src/com/google/inject/internal/BytecodeGen.java#L245 - FastClass.Generator is a sub class of AbstractClassGenerator - AbstractClassGenerator supports caching of generated classes: https://github.com/cglib/cglib/blob/master/cglib/src/main/java/net/sf/cglib/core/AbstractClassGenerator.java#L116 - Maybe I am wrong but the primary lookup key for the generated classes is the FastClass.Generator instance itself - FastClass.Generator does not implement hashCode() and equals() - Guice creates a new generator for every type and member and hence the cached class is NEVER used - This effectively means that Guice creates a new FastClass for EVERY injection point (slow) My proposed fix:
- use a WeakHashMap in ByteCodeGen to cache ClassLoader -> FastClass.Generator instances - use the class loader of the target type as key to lookup or create FastClass.Generator instance at this line https://github.com/google/guice/blob/master/core/src/com/google/inject/internal/BytecodeGen.java#L245 I hope this helps to create a fix for this issue. Any comments are welcome. Best regards, Ken Am Freitag, 9. September 2016 14:05:10 UTC+2 schrieb Ken Wenzel: > > I use the method Injector.createChildInjector(...) to create many > injectors with different configurations in my application. > Each of those injectors is only used for a short period of time and then > garbage collected. > > Now it seems that for each injector an own set of fast classes is created > for each SingleMethodInjector and others. > For an example look at: > > https://github.com/google/guice/blob/f905d59ac9c3c1ad57c755a1abb29c4fb2d6b7fa/core/src/com/google/inject/internal/SingleMethodInjector.java#L46 > > These fast classes (or at least meta data about them) are kept within a > global map. > The Eclipse Memory Analyzer classifies this as a leak suspect: > > One instance of "java.util.HashSet" loaded by "<system class loader>" > occupies 671,209,552 (79.21%) bytes. > The instance is referenced by > com.google.inject.internal.cglib.core.$AbstractClassGenerator$1 > @ 0xfff4c7a0 , > loaded by "com.google.inject". The memory is accumulated in one instance > of "java.util.HashMap$Node[]" loaded by "<system class loader>". > > > I think it should be possible for Guice to share the fast classes between > different injectors. > > Any help is appreciated. > > Thank you and best regards, > Ken > > -- You received this message because you are subscribed to the Google Groups "google-guice" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/google-guice. To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/64a8a75b-58f5-4bbb-9c7a-4f07f3dc0f73%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
