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.

Reply via email to