PermGen growth

96 views
Skip to first unread message

Greg Harman

unread,
Jan 25, 2009, 2:26:39 AM1/25/09
to Clojure
I'm trying to debug a problem in one of my programs in which PermGen
usage grows with and during each run (cumulatively within the same
REPL session) until I eventually run out & get the out of memory JVM
exception. So I wrote the following utility just to help me track
usage while I hack:

(defn permGen
[]
(let [beans (java.lang.management.ManagementFactory/
getMemoryPoolMXBeans)]
(doseq [mx beans]
(when (= "Perm Gen" (.getName mx))
(println (.getUsage mx))))))

I ran this several times in succession:

gp=> (permGen)
#<MemoryUsage init = 16777216(16384K) used = 11035288(10776K)
committed = 16777216(16384K) max = 67108864(65536K)>
nil
gp=> (permGen)
#<MemoryUsage init = 16777216(16384K) used = 11036888(10778K)
committed = 16777216(16384K) max = 67108864(65536K)>
nil
gp=> (permGen)
#<MemoryUsage init = 16777216(16384K) used = 11038488(10779K)
committed = 16777216(16384K) max = 67108864(65536K)>
nil
gp=> (permGen)
#<MemoryUsage init = 16777216(16384K) used = 11040088(10781K)
committed = 16777216(16384K) max = 67108864(65536K)>

The thing to notice is that the used PermGen has grown by 1-2K with
each run (I ran it many more times than I pasted, and that growth rate
seems pretty steady). What I don't understand is why. If I understand
PermGen correctly, it holds class definitions. In Clojure classes are
only generated with calls to fn (see
http://groups.google.com/group/clojure/browse_thread/thread/2c66650b9057f760/11a09103da821264?lnk=gst&q=permgen#11a09103da821264),
and I don't have any sort of nested function creation inside my
(permGen) function.

I don't have any anonymous function definitions in my function, so
what is causing the used PermGen growth?

thanks,
Greg

Christian Vest Hansen

unread,
Jan 25, 2009, 5:57:56 AM1/25/09
to clo...@googlegroups.com
Clojure creates class not for every function call, but for every
function definition.

The PermGen growth you see is the REPL compiling your input, most likely.
--
Venlig hilsen / Kind regards,
Christian Vest Hansen.

Greg Harman

unread,
Jan 25, 2009, 9:08:07 AM1/25/09
to Clojure
I believe you, but I don't understand why. I'm doing nothing but
evaluate my test function over and over. Since no new functions are
being defined, why would this evaluation use any PermGen?

On Jan 25, 5:57 am, Christian Vest Hansen <karmazi...@gmail.com>
wrote:

Christian Vest Hansen

unread,
Jan 25, 2009, 9:33:39 AM1/25/09
to clo...@googlegroups.com
When the reader has a top-level expression in the REPL, it gets
evaluated. Evaluation goes through the Compiler which generates
bytecode from your forms. Before the bytecode can be executed, it
needs to be loaded into the JVM, and that happens by wrapping it in a
class and loading that.

Christian Vest Hansen

unread,
Jan 25, 2009, 9:40:24 AM1/25/09
to clo...@googlegroups.com
To clarify:

On Sun, Jan 25, 2009 at 3:08 PM, Greg Harman <gha...@gmail.com> wrote:
>
> I believe you, but I don't understand why. I'm doing nothing but
> evaluate my test function over and over.

Exactly. This input is evaluated and compiled over and over.

> Since no new functions are
> being defined,

The expression to call your function was being defined over and over,
causing new classes to be generated.

This is a side-effect of eval, which the REPL is based upon.

> why would this evaluation use any PermGen?
>
> On Jan 25, 5:57 am, Christian Vest Hansen <karmazi...@gmail.com>
> wrote:
>> Clojure creates class not for every function call, but for every
>> function definition.
>>
>> The PermGen growth you see is the REPL compiling your input, most likely.
>
> >
>



Greg Harman

unread,
Jan 25, 2009, 9:54:09 AM1/25/09
to Clojure
I see, so running (permGen) 10 times from the REPL is not the same as,
say, (dotimes [_ 10] (permGen)), because there's an understood (eval)
around anything executed directly in the REPL.

Thanks.

On Jan 25, 9:33 am, Christian Vest Hansen <karmazi...@gmail.com>
wrote:
> When the reader has a top-level expression in the REPL, it gets
> evaluated. Evaluation goes through the Compiler which generates
> bytecode from your forms. Before the bytecode can be executed, it
> needs to be loaded into the JVM, and that happens by wrapping it in a
> class and loading that.
>
Reply all
Reply to author
Forward
0 new messages