1

In this web-based Maven project I'm working on, I'm trying to use some Groovy code on top of my existing Java code. So far, I have been getting the epic "java.lang.OutOfMemoryError: PermGen space" whenever I tried invoking some Groovy-created object from Java. The web project runs on Jetty, using Jetty Maven Plugin.

I have increased the perm size to the following:-

export MAVEN_OPTS="-Xms2048m -Xmx2048m -XX:PermSize=512m -XX:MaxPermSize=1024m"

I'm seeing the same problem when using either GMaven 1.5 or Groovy-eclipse-compiler 2.8.0-01.

For example, in this Spring MVC controller, I'm using Stuff object, which is a simple POGO. By the way, this is the only Groovy code used in my entire Java EE project.

@Controller
@RequestMapping(value = "/")
public class HomeController {

    @RequestMapping(method = RequestMethod.GET)
    public String main() {
        Stuff stuff = new Stuff();
        stuff.setName("Bla");
        System.out.println(stuff.getName());
        return "home";
    }
}

When I hit the controller from the web, I'm getting this:-

java.lang.OutOfMemoryError: PermGen space
    at java.lang.ClassLoader.findBootstrapClass(Native Method)
    at java.lang.ClassLoader.findBootstrapClassOrNull(ClassLoader.java:926)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:297)
    at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)
    at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:407)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:383)
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2475)
    at java.lang.Class.getDeclaredMethods(Class.java:1818)
    at org.codehaus.groovy.reflection.CachedClass$3$1.run(CachedClass.java:84)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.codehaus.groovy.reflection.CachedClass$3.initValue(CachedClass.java:81)
    at org.codehaus.groovy.reflection.CachedClass$3.initValue(CachedClass.java:79)
    at org.codehaus.groovy.util.LazyReference.getLocked(LazyReference.java:46)
    at org.codehaus.groovy.util.LazyReference.get(LazyReference.java:33)
    at org.codehaus.groovy.reflection.CachedClass.getMethods(CachedClass.java:250)
    at org.codehaus.groovy.runtime.m12n.SimpleExtensionModule.createMetaMethods(SimpleExtensionModule.java:111)
    at org.codehaus.groovy.runtime.m12n.SimpleExtensionModule.getMetaMethods(SimpleExtensionModule.java:93)
    at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerExtensionModuleFromProperties(MetaClassRegistryImpl.java:192)
    at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerExtensionModuleFromMetaInf(MetaClassRegistryImpl.java:174)
    at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerClasspathModules(MetaClassRegistryImpl.java:156)
    at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:111)
    at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:73)
    at groovy.lang.GroovySystem.<clinit>(GroovySystem.java:33)
    at org.codehaus.groovy.reflection.ClassInfo.getMetaClassUnderLock(ClassInfo.java:162)
    at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:192)
    at myproject.bean.Stuff.$getStaticMetaClass(Stuff.groovy)
    at myproject.bean.Stuff.<init>(Stuff.groovy)
    at myproject.controller.HomeController.main(HomeController.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

If I commented out that 3 lines of Groovy code from my controller class, everything works just fine without error:-

@Controller
@RequestMapping(value = "/")
public class HomeController {

    @RequestMapping(method = RequestMethod.GET)
    public String main() {
        //Stuff stuff = new Stuff();
        //stuff.setName("Bla");
        //System.out.println(stuff.getName());
        return "home";
    }
}

How do I fix this problem? Thanks.

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
limc
  • 39,366
  • 20
  • 100
  • 145

1 Answers1

0

-XX:MaxPermSize=1024m is a lot. This sounds like a memory leak somewhere in a classloader. I suggest to fire up your profiler and analyze the classloaders that are active. One of them should have lots of classes loaded.

If you still use Java 5, try Java 7. If you really want to stay on 5, make sure you add -XX:+CMSPermGenSweepingEnabled to the Java startup options.

Related:

Community
  • 1
  • 1
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • Hello @Aaron, I have tried `MaxPermSize` of 256m and 512m too, but I'm still seeing the same error. I'm currently using Java 6, and that's the only version I can use to mimic our production environment. – limc Oct 18 '13 at 13:45
  • 1
    I figured out the problem. IntelliJ doesn't seem to honor MAVEN_OPTS. It works fine when I run `mvn clean jetty:run` from Terminal, but I see the same error when running Jetty from IntelliJ. The fix is to set the `MaxPermSize` in IntelliJ's Maven Runner's VM options. – limc Oct 18 '13 at 14:16