Re: class loaders stack constant grow in REPL
Good catch, guys. Interesting that I never noticed this; likely because Pomegranate's `classloader-hierarchy` function ends up starting its walk from (RT/baseLoader) (which will be changing to the context classloader shortly): https://github.com/cemerick/pomegranate/blob/master/src/main/clojure/cemerick/pomegranate.clj#L54 I'm open to suggestions. I'm not keen on having yet another divergence in nREPL behaviour between 1.5.0 and all prior revs of Clojure, so an nREPL-local fix would be great. My first impulse right now is to boot clojure.main/repl entirely and groom a replacement "in-house", as it were (which I probably should have done from day 1). - Chas On Dec 10, 2012, at 11:32 AM, Colin Jones wrote: > Right, this is because nREPL uses clojure.main/repl each time it does an > evaluation. See http://dev.clojure.org/jira/browse/NREPL-31 for a related > issue that was addressed by modifying clojure.main/repl. > > I'm not sure where a fix for this would belong (nREPL or clojure.main), but I > went ahead and opened an nREPL JIRA issue to track it: > http://dev.clojure.org/jira/browse/NREPL-36 > > - Colin > > > > > On Monday, December 10, 2012 2:46:10 AM UTC-6, Vladimir Tsichevski wrote: > Hi, > > just found that every interaction with Clojure REPL causes one more > DynamicClassLoader put on the Thread context class loader chain. > > Here is how clojure.main/repl beginning looks like: > > (let [cl (.getContextClassLoader (Thread/currentThread))] > (.setContextClassLoader (Thread/currentThread) > (clojure.lang.DynamicClassLoader. cl))) > > And this is how to observe it: > > nREPL server started on port 19987 > REPL-y 0.1.0-beta10 > Clojure 1.4.0 > Exit: Control+D or (exit) or (quit) > Commands: (user/help) > Docs: (doc function-name-here) > (find-doc "part-of-name-here") > Source: (source function-name-here) > (user/sourcery function-name-here) > Javadoc: (javadoc java-object-or-class-here) > Examples from clojuredocs.org: [clojuredocs or cdoc] > (user/clojuredocs name-here) > (user/clojuredocs "ns-here" "name-here") > user=> (defn print-class-loader-stack > ([] > (print-class-loader-stack (.getContextClassLoader > (Thread/currentThread > ([cl] > (if cl >(do > (pprint cl) > (print-class-loader-stack (.getParent cl))) >(println "*Top*" > #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> > #'user/print-class-loader-stack > user=> (print-class-loader-stack) > # > # > # > # > # > # > *Top* > nil > user=> 1 > 1 > user=> 1 > 1 > user=> 1 > 1 > user=> 1 > 1 > user=> (print-class-loader-stack) > # > # > # > # > # > # > # > # > # > # > # > *Top* > nil > user=> > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: class loaders stack constant grow in REPL
Colin Jones writes: Hi Colin, > Right, this is because nREPL uses clojure.main/repl each time it does > an evaluation. See http://dev.clojure.org/jira/browse/NREPL-31 for a > related issue that was addressed by modifying clojure.main/repl. > > I'm not sure where a fix for this would belong (nREPL or > clojure.main), but I went ahead and opened an nREPL JIRA issue to > track it: http://dev.clojure.org/jira/browse/NREPL-36 Some time ago, I was also astonished by the large number of class loaders. But I'm pretty sure that the class loader list (i.e., ClassLoader.parent -> ClassLoader.parent -> ...) didn't grow without bounds, but sometimes a parent becomes set to null and the previously referenced class loader and all its parents becomes garbage collected. I didn't do any debugging, but just used a function similar to Vladimir's `print-class-loader-stack` every once in a while. Bye, Tassilo -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: class loaders stack constant grow in REPL
Thank you Colin, I think, the main problem is nobody has ever tried to write an article "Class loading in Clojure". If such article existed, it would make life much easier for many developers. Regards, Vladimir On Monday, December 10, 2012 8:32:36 PM UTC+4, Colin Jones wrote: > > Right, this is because nREPL uses clojure.main/repl each time it does an > evaluation. See http://dev.clojure.org/jira/browse/NREPL-31 for a related > issue that was addressed by modifying clojure.main/repl. > > I'm not sure where a fix for this would belong (nREPL or clojure.main), > but I went ahead and opened an nREPL JIRA issue to track it: > http://dev.clojure.org/jira/browse/NREPL-36 > > - Colin > > > > > On Monday, December 10, 2012 2:46:10 AM UTC-6, Vladimir Tsichevski wrote: >> >> Hi, >> >> just found that every interaction with Clojure REPL causes one >> more DynamicClassLoader put on the Thread context class loader chain. >> >> Here is how clojure.main/repl beginning looks like: >> >> (let [cl (.getContextClassLoader (Thread/currentThread))] >> (.setContextClassLoader (Thread/currentThread) >> (clojure.lang.DynamicClassLoader. cl))) >> >> And this is how to observe it: >> >> nREPL server started on port 19987 >> REPL-y 0.1.0-beta10 >> Clojure 1.4.0 >> Exit: Control+D or (exit) or (quit) >> Commands: (user/help) >> Docs: (doc function-name-here) >> (find-doc "part-of-name-here") >> Source: (source function-name-here) >> (user/sourcery function-name-here) >> Javadoc: (javadoc java-object-or-class-here) >> Examples from clojuredocs.org: [clojuredocs or cdoc] >> (user/clojuredocs name-here) >> (user/clojuredocs "ns-here" "name-here") >> user=> (defn print-class-loader-stack >> ([] >> (print-class-loader-stack (.getContextClassLoader >> (Thread/currentThread >> ([cl] >> (if cl >>(do >> (pprint cl) >> (print-class-loader-stack (.getParent cl))) >>(println "*Top*" >> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> >> #'user/print-class-loader-stack >> user=> (print-class-loader-stack) >> # >> # >> # >> # >> # >> # >> *Top* >> nil >> user=> 1 >> 1 >> user=> 1 >> 1 >> user=> 1 >> 1 >> user=> 1 >> 1 >> user=> (print-class-loader-stack) >> # >> # >> # >> # >> # >> # >> # >> # >> # >> # >> # >> *Top* >> nil >> user=> >> > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: class loaders stack constant grow in REPL
Right, this is because nREPL uses clojure.main/repl each time it does an evaluation. See http://dev.clojure.org/jira/browse/NREPL-31 for a related issue that was addressed by modifying clojure.main/repl. I'm not sure where a fix for this would belong (nREPL or clojure.main), but I went ahead and opened an nREPL JIRA issue to track it: http://dev.clojure.org/jira/browse/NREPL-36 - Colin On Monday, December 10, 2012 2:46:10 AM UTC-6, Vladimir Tsichevski wrote: > > Hi, > > just found that every interaction with Clojure REPL causes one > more DynamicClassLoader put on the Thread context class loader chain. > > Here is how clojure.main/repl beginning looks like: > > (let [cl (.getContextClassLoader (Thread/currentThread))] > (.setContextClassLoader (Thread/currentThread) > (clojure.lang.DynamicClassLoader. cl))) > > And this is how to observe it: > > nREPL server started on port 19987 > REPL-y 0.1.0-beta10 > Clojure 1.4.0 > Exit: Control+D or (exit) or (quit) > Commands: (user/help) > Docs: (doc function-name-here) > (find-doc "part-of-name-here") > Source: (source function-name-here) > (user/sourcery function-name-here) > Javadoc: (javadoc java-object-or-class-here) > Examples from clojuredocs.org: [clojuredocs or cdoc] > (user/clojuredocs name-here) > (user/clojuredocs "ns-here" "name-here") > user=> (defn print-class-loader-stack > ([] > (print-class-loader-stack (.getContextClassLoader > (Thread/currentThread > ([cl] > (if cl >(do > (pprint cl) > (print-class-loader-stack (.getParent cl))) >(println "*Top*" > #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> > #'user/print-class-loader-stack > user=> (print-class-loader-stack) > # > # > # > # > # > # > *Top* > nil > user=> 1 > 1 > user=> 1 > 1 > user=> 1 > 1 > user=> 1 > 1 > user=> (print-class-loader-stack) > # > # > # > # > # > # > # > # > # > # > # > *Top* > nil > user=> > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
class loaders stack constant grow in REPL
Hi, just found that every interaction with Clojure REPL causes one more DynamicClassLoader put on the Thread context class loader chain. Here is how clojure.main/repl beginning looks like: (let [cl (.getContextClassLoader (Thread/currentThread))] (.setContextClassLoader (Thread/currentThread) (clojure.lang.DynamicClassLoader. cl))) And this is how to observe it: nREPL server started on port 19987 REPL-y 0.1.0-beta10 Clojure 1.4.0 Exit: Control+D or (exit) or (quit) Commands: (user/help) Docs: (doc function-name-here) (find-doc "part-of-name-here") Source: (source function-name-here) (user/sourcery function-name-here) Javadoc: (javadoc java-object-or-class-here) Examples from clojuredocs.org: [clojuredocs or cdoc] (user/clojuredocs name-here) (user/clojuredocs "ns-here" "name-here") user=> (defn print-class-loader-stack ([] (print-class-loader-stack (.getContextClassLoader (Thread/currentThread ([cl] (if cl (do (pprint cl) (print-class-loader-stack (.getParent cl))) (println "*Top*" #_=> #_=> #_=> #_=> #_=> #_=> #_=> #_=> #'user/print-class-loader-stack user=> (print-class-loader-stack) # # # # # # *Top* nil user=> 1 1 user=> 1 1 user=> 1 1 user=> 1 1 user=> (print-class-loader-stack) # # # # # # # # # # # *Top* nil user=> -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en