Hi, Am 25.01.2009 um 08:41 schrieb Greg Harman:
This could be a real problem for Clojure. I can think of other techniques that could easily result in the creation a large number of anonymous functions that ought to get gc'd after a few ms but permanently increase memory usage by a significant amount. I don't know the JVM very well at all. Are there any ways around this? Are techniques that generate a lot of short-lived functions just not practical in Clojure?It seems that anonymous functions in general might be a sort of anti- pattern. Beyond deeply-nested applications like GP, there's the case of any long-running process e.g. pretty much any server application. The growth might be slower, but sooner or later that server is going to accumulate too many...
Disclaimer: Every information of the Clojure internals in the following are impressions I got from reading the list. So they might be true or they might not be true. Every function in Clojure creates a class. So if one encounters a (fn [a b] (+ a b)) at runtime, there is simply a new class instance created, which is then .invoked with values for a and b. So the number of "functions" is known at compile time. Note: macros happen at compile-time, so functions generated by a macro are also known at compile-time. At runtime there is simply an instance which gets gc'd. So saying "anonymous functions in general might be a sort of anti-pattern" is equal to saying "Vectors in general might be sort of anti-pattern", because there is nothing different happening. I didn't follow the thread in much detail, but that is what I have left in my memory: What might be an anti-pattern is using eval. Ok ok. I know eval has its uses, but using eval with fn might be an anti-pattern. From my point of view, the following is happening: One calls (eval '(fn ....)). Each and every call to eval creates a new class. Even for identical fn's. So what cloggs the memory are not the function instances themselves. They get gc'd. But the generated classes stay in memory. They don't go away. This is what brings down the system finally. (eval '(fn ..)) should not be a thing you should find in a "long running server application". Maybe only in form of debug repl. But generating enough fn classes in that repl to bring down the server.... Does this make sense? Sincerely Meikel
smime.p7s
Description: S/MIME cryptographic signature