google-code-export / google-guice

Automatically exported from code.google.com/p/google-guice
Apache License 2.0
2 stars 1 forks source link

Guice leaks permgen space #200

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Calling this method leaks memory - approximately 2Kb worth:
  public void leakMemory() {
    Guice.createInjector(new AbstractModule() {
      protected void configure() {
        bindInterceptor(Matchers.any(), Matchers.any(), new MethodInterceptor() {
          public Object invoke(MethodInvocation methodInvocation) throws Throwable {
            return methodInvocation.proceed();
          }
        });
      }
    }).getInstance(A.class);
  }

We could fix this problem by using a private classloader for cglib classes 
created by Guice. That 
should make the generated subclasses of A.class eligible for garbage collection 
once the 
originating injector and all instances go out of scope.

This problem isn't as much a big deal unless users are creating lots of 
injectors. But we tend to 
be encouraging that pattern with hierarchical injectors etc.

net.sf.cglib.core.CodeGenerationException: 
java.lang.reflect.InvocationTargetException-->null
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
    at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at net.sf.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
    at com.google.inject.ProxyFactory.createConstructionProxy(ProxyFactory.java:159)
    at com.google.inject.ProxyFactory$1.create(ProxyFactory.java:61)
    at com.google.inject.ProxyFactory$1.create(ProxyFactory.java:60)
    at com.google.inject.internal.ReferenceCache.create(ReferenceCache.java:53)
    at 
com.google.inject.internal.AbstractReferenceCache.internalCreate(AbstractReferen
ceCache.java:5
9)
    at com.google.inject.internal.AbstractReferenceCache.get(AbstractReferenceCache.java:116)
    at com.google.inject.ProxyFactory.get(ProxyFactory.java:215)
    at 
com.google.inject.RuntimeReflectionFactory$RuntimeReflection.getConstructionProx
y(RuntimeRe
flectionFactory.java:45)
    at com.google.inject.ConstructorInjector.<init>(ConstructorInjector.java:38)
    at com.google.inject.InjectorImpl$9.create(InjectorImpl.java:1014)
    at com.google.inject.InjectorImpl$9.create(InjectorImpl.java:1005)
    at com.google.inject.internal.ReferenceCache.create(ReferenceCache.java:53)
    at 
com.google.inject.internal.AbstractReferenceCache.internalCreate(AbstractReferen
ceCache.java:5
9)
    at com.google.inject.internal.AbstractReferenceCache.get(AbstractReferenceCache.java:116)
    at com.google.inject.InjectorImpl.getConstructor(InjectorImpl.java:1175)
    at com.google.inject.InjectorImpl$LateBoundConstructor.bind(InjectorImpl.java:578)
    at com.google.inject.ClassBindingImpl.initialize(ClassBindingImpl.java:45)
    at com.google.inject.InjectorImpl.initializeBinding(InjectorImpl.java:511)
    at com.google.inject.InjectorImpl.createBindingFromType(InjectorImpl.java:496)
    at com.google.inject.InjectorImpl.createBindingFromType(InjectorImpl.java:490)
    at com.google.inject.InjectorImpl.createBindingJustInTime(InjectorImpl.java:717)
    at com.google.inject.InjectorImpl.getJitBindingImpl(InjectorImpl.java:255)
    at com.google.inject.InjectorImpl.getBindingOrThrow(InjectorImpl.java:191)
    at com.google.inject.InjectorImpl.getInternalFactory(InjectorImpl.java:722)
    at com.google.inject.InjectorImpl.getProviderOrThrow(InjectorImpl.java:1094)
    at com.google.inject.InjectorImpl.getProvider(InjectorImpl.java:1125)
    at com.google.inject.InjectorImpl.getProvider(InjectorImpl.java:1090)
    at com.google.inject.InjectorImpl.getInstance(InjectorImpl.java:1137)
    at com.google.inject.MemoryLeakinessTest.leakMemory(MemoryLeakinessTest.java:49)
    at com.google.inject.MemoryLeakinessTest.testLeakMemory(MemoryLeakinessTest.java:35)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.jav
a:25)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.jav
a:25)
    at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
    ... 48 more
Caused by: java.lang.OutOfMemoryError: PermGen space
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:675)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.jav
a:25)
    at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
    at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at net.sf.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
    at com.google.inject.ProxyFactory.createConstructionProxy(ProxyFactory.java:159)
    at com.google.inject.ProxyFactory$1.create(ProxyFactory.java:61)
    at com.google.inject.ProxyFactory$1.create(ProxyFactory.java:60)
    at com.google.inject.internal.ReferenceCache.create(ReferenceCache.java:53)
    at 
com.google.inject.internal.AbstractReferenceCache.internalCreate(AbstractReferen
ceCache.java:5
9)
    at com.google.inject.internal.AbstractReferenceCache.get(AbstractReferenceCache.java:116)
    at com.google.inject.ProxyFactory.get(ProxyFactory.java:215)
    at 
com.google.inject.RuntimeReflectionFactory$RuntimeReflection.getConstructionProx
y(RuntimeRe
flectionFactory.java:45)
    at com.google.inject.ConstructorInjector.<init>(ConstructorInjector.java:38)
    at com.google.inject.InjectorImpl$9.create(InjectorImpl.java:1014)
    at com.google.inject.InjectorImpl$9.create(InjectorImpl.java:1005)
    at com.google.inject.internal.ReferenceCache.create(ReferenceCache.java:53)
    at 
com.google.inject.internal.AbstractReferenceCache.internalCreate(AbstractReferen
ceCache.java:5
9)
    at com.google.inject.internal.AbstractReferenceCache.get(AbstractReferenceCache.java:116)
    at com.google.inject.InjectorImpl.getConstructor(InjectorImpl.java:1175)
    at com.google.inject.InjectorImpl$LateBoundConstructor.bind(InjectorImpl.java:578)
    at com.google.inject.ClassBindingImpl.initialize(ClassBindingImpl.java:45)
    at com.google.inject.InjectorImpl.initializeBinding(InjectorImpl.java:511)
    at com.google.inject.InjectorImpl.createBindingFromType(InjectorImpl.java:496)
    at com.google.inject.InjectorImpl.createBindingFromType(InjectorImpl.java:490)
    at com.google.inject.InjectorImpl.createBindingJustInTime(InjectorImpl.java:717)
    at com.google.inject.InjectorImpl.getJitBindingImpl(InjectorImpl.java:255)
    at com.google.inject.InjectorImpl.getBindingOrThrow(InjectorImpl.java:191)

Original issue reported on code.google.com by limpbizkit on 23 May 2008 at 5:49

GoogleCodeExporter commented 9 years ago
Attached is a suggested patch that provides a custom classloader for Guice 
generated
proxies (not enabled by default, can be turned on using 
"-Dguice.custom.loader=true")

  javac -cp ".;guice.jar;aopalliance.jar" leak.java

  # will eventually hit an OOM because of the generated class leak
  java -cp ".;guice.jar;aopalliance.jar" -Xmx8m -verbose:gc leak

  # should keep on running, every now and then unloading a shed-load of generated classes
  java -cp ".;guice.jar;aopalliance.jar" -Xmx8m -verbose:gc
-Dguice.custom.loader=true leak

Original comment by mccu...@gmail.com on 4 Jun 2008 at 9:26

Attachments:

GoogleCodeExporter commented 9 years ago
Updated patch that includes a couple of the extensions that also create proxies.

Original comment by mccu...@gmail.com on 4 Jun 2008 at 11:44

Attachments:

GoogleCodeExporter commented 9 years ago
This is being fixed by mcculls' OSGi patch, being tracked by issue 94.

Original comment by limpbizkit on 29 Jun 2008 at 11:07

GoogleCodeExporter commented 9 years ago
http://code.google.com/p/google-guice/wiki/BytecodeGeneration

Original comment by limpbizkit on 3 Jul 2008 at 10:03