ninjudd / cake

A tasty build tool for Clojure.
clojure-cake.org
Eclipse Public License 1.0
171 stars 12 forks source link

Cake crashes regularly with java.lang.OutOfMemoryError: PermGen space #132

Closed jwr closed 12 years ago

jwr commented 13 years ago

Once every several runs cake will crash with java.lang.OutOfMemoryError: PermGen space. This is so frequent so as to negate the benefits of the persistently-running cake JVM, as I regularly have to kill jvms, restart cake, rebuild everything.

This is with cake 0.6.3 installed from brew on Mac OS X 10.7.

The usual sequence is:

  [compile] Compiling namespace fablo.main
java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid26897.hprof ...
Heap dump file created [135659349 bytes in 2.896 secs]
error evaluating:
((compile-stale source-path compile-path))

but sometimes this happens in other stages as well:

cake deps
  [pom.xml] generating file
     [deps] Fetching dependencies...
     [deps] Copying 56 files to /jwr/fablo/poligon/build/lib
     [deps] Copying 7 files to /jwr/fablo/poligon/build/lib/dev
     [deps] Deleting directory /jwr/fablo/poligon/lib
     [deps] Attempting to rename dir: build/lib to lib
    [clean] Deleting /jwr/fablo/poligon/.cake/run/clean
java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid11241.hprof ...
Heap dump file created [135927681 bytes in 2.348 secs]
java.lang.OutOfMemoryError: PermGen space
 at java.lang.ClassLoader.defineClass1 (ClassLoader.java:-2)
    java.lang.ClassLoader.defineClassCond (ClassLoader.java:631)
    java.lang.ClassLoader.defineClass (ClassLoader.java:615)
    java.security.SecureClassLoader.defineClass (SecureClassLoader.java:141)
    java.net.URLClassLoader.defineClass (URLClassLoader.java:283)
    java.net.URLClassLoader.access$000 (URLClassLoader.java:58)
    java.net.URLClassLoader$1.run (URLClassLoader.java:197)
    java.security.AccessController.doPrivileged (AccessController.java:-2)
    java.net.URLClassLoader.findClass (URLClassLoader.java:190)
    java.lang.ClassLoader.loadClass (ClassLoader.java:306)
    java.lang.ClassLoader.loadClass (ClassLoader.java:247)
    clojure.java.io__init.load (:228)
    clojure.java.io__init.<clinit> (:-1)
    java.lang.Class.forName0 (Class.java:-2)
    java.lang.Class.forName (Class.java:247)
    clojure.lang.RT.loadClassForName (RT.java:2030)
    clojure.lang.RT.load (RT.java:417)
    clojure.lang.RT.load (RT.java:398)
    clojure.core$load$fn__4610.invoke (core.clj:5386)
    clojure.core$load.doInvoke (core.clj:5385)
    clojure.lang.RestFn.invoke (RestFn.java:408)
    clojure.core$load_one.invoke (core.clj:5200)
    clojure.core$load_lib.doInvoke (core.clj:5237)
    clojure.lang.RestFn.applyTo (RestFn.java:142)
    clojure.core$apply.invoke (core.clj:602)
    clojure.core$load_libs.doInvoke (core.clj:5271)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invoke (core.clj:602)
    clojure.core$require.doInvoke (core.clj:5352)
    clojure.lang.RestFn.invoke (RestFn.java:408)
    clojure.core__init.load (:6007)
    clojure.core__init.<clinit> (:-1)

or even in clean:

    [clean] Deleting /jwr/fablo/poligon/.cake/run/clean
java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid20294.hprof ...
Heap dump file created [140607277 bytes in 2.996 secs]
java.lang.OutOfMemoryError: PermGen space
 at java.lang.ClassLoader.defineClass1 (ClassLoader.java:-2)
    java.lang.ClassLoader.defineClassCond (ClassLoader.java:631)
    java.lang.ClassLoader.defineClass (ClassLoader.java:615)
    java.security.SecureClassLoader.defineClass (SecureClassLoader.java:141)
    java.net.URLClassLoader.defineClass (URLClassLoader.java:283)
    java.net.URLClassLoader.access$000 (URLClassLoader.java:58)
    java.net.URLClassLoader$1.run (URLClassLoader.java:197)
    java.security.AccessController.doPrivileged (AccessController.java:-2)
    java.net.URLClassLoader.findClass (URLClassLoader.java:190)
    java.lang.ClassLoader.loadClass (ClassLoader.java:306)
    java.lang.ClassLoader.loadClass (ClassLoader.java:247)
    clojure.core__init.load (:2537)
    clojure.core__init.<clinit> (:-1)
    java.lang.Class.forName0 (Class.java:-2)
    java.lang.Class.forName (Class.java:247)
    clojure.lang.RT.loadClassForName (RT.java:1578)
    clojure.lang.RT.load (RT.java:399)
    clojure.lang.RT.load (RT.java:381)
    clojure.lang.RT.doInit (RT.java:416)
    clojure.lang.RT.<clinit> (RT.java:302)
    sun.reflect.NativeMethodAccessorImpl.invoke0 (NativeMethodAccessorImpl.java:-2)
    sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke (Method.java:597)
    sun.reflect.GeneratedMethodAccessor147.invoke (:-1)
    sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke (Method.java:597)
    clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:90)
    clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:28)
    classlojure$invoke_in_STAR_.doInvoke (classlojure.clj:37)
    clojure.lang.RestFn.invoke (RestFn.java:495)
    classlojure$eval_in$fn__1114.invoke (classlojure.clj:56)
ninjudd commented 13 years ago

This happens when your project classloaders cannot be garbage collected, because a class in some dependency is being held onto by some class in Java's system classloader. The most common culprit is SQL adapters. The fix is to find which dependency is causing the problem and make it an ext dependency. For example, in our internal project, we do this with postgres and tokyocabinet:

 :ext-dependencies [[tokyocabinet "1.24.1-SNAPSHOT"]
                    [postgresql/postgresql "8.4-701.jdbc4"]]
ninjudd commented 12 years ago

Closing since we're moving to lein