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) #DynamicClassLoader clojure.lang.DynamicClassLoader@26a0c73f #DynamicClassLoader clojure.lang.DynamicClassLoader@6f603bdc #DynamicClassLoader clojure.lang.DynamicClassLoader@2f368c5d #DynamicClassLoader clojure.lang.DynamicClassLoader@5b31fd9 #AppClassLoader sun.misc.Launcher$AppClassLoader@4aad3ba4 #ExtClassLoader sun.misc.Launcher$ExtClassLoader@3326b249 *Top* nil user= 1 1 user= 1 1 user= 1 1 user= 1 1 user= (print-class-loader-stack) #DynamicClassLoader clojure.lang.DynamicClassLoader@5be04861 #DynamicClassLoader clojure.lang.DynamicClassLoader@7481933a #DynamicClassLoader clojure.lang.DynamicClassLoader@273f212a #DynamicClassLoader clojure.lang.DynamicClassLoader@4178feba #DynamicClassLoader clojure.lang.DynamicClassLoader@5323961b #DynamicClassLoader clojure.lang.DynamicClassLoader@26a0c73f #DynamicClassLoader clojure.lang.DynamicClassLoader@6f603bdc #DynamicClassLoader clojure.lang.DynamicClassLoader@2f368c5d #DynamicClassLoader clojure.lang.DynamicClassLoader@5b31fd9 #AppClassLoader sun.misc.Launcher$AppClassLoader@4aad3ba4 #ExtClassLoader sun.misc.Launcher$ExtClassLoader@3326b249 *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) #DynamicClassLoader clojure.lang.DynamicClassLoader@26a0c73f #DynamicClassLoader clojure.lang.DynamicClassLoader@6f603bdc #DynamicClassLoader clojure.lang.DynamicClassLoader@2f368c5d #DynamicClassLoader clojure.lang.DynamicClassLoader@5b31fd9 #AppClassLoader sun.misc.Launcher$AppClassLoader@4aad3ba4 #ExtClassLoader sun.misc.Launcher$ExtClassLoader@3326b249 *Top* nil user= 1 1 user= 1 1 user= 1 1 user= 1 1 user= (print-class-loader-stack) #DynamicClassLoader clojure.lang.DynamicClassLoader@5be04861 #DynamicClassLoader clojure.lang.DynamicClassLoader@7481933a #DynamicClassLoader clojure.lang.DynamicClassLoader@273f212a #DynamicClassLoader clojure.lang.DynamicClassLoader@4178feba #DynamicClassLoader clojure.lang.DynamicClassLoader@5323961b #DynamicClassLoader clojure.lang.DynamicClassLoader@26a0c73f #DynamicClassLoader clojure.lang.DynamicClassLoader@6f603bdc #DynamicClassLoader clojure.lang.DynamicClassLoader@2f368c5d #DynamicClassLoader clojure.lang.DynamicClassLoader@5b31fd9 #AppClassLoader sun.misc.Launcher$AppClassLoader@4aad3ba4 #ExtClassLoader sun.misc.Launcher$ExtClassLoader@3326b249 *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
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) #DynamicClassLoader clojure.lang.DynamicClassLoader@26a0c73f #DynamicClassLoader clojure.lang.DynamicClassLoader@6f603bdc #DynamicClassLoader clojure.lang.DynamicClassLoader@2f368c5d #DynamicClassLoader clojure.lang.DynamicClassLoader@5b31fd9 #AppClassLoader sun.misc.Launcher$AppClassLoader@4aad3ba4 #ExtClassLoader sun.misc.Launcher$ExtClassLoader@3326b249 *Top* nil user= 1 1 user= 1 1 user= 1 1 user= 1 1 user= (print-class-loader-stack) #DynamicClassLoader clojure.lang.DynamicClassLoader@5be04861 #DynamicClassLoader clojure.lang.DynamicClassLoader@7481933a #DynamicClassLoader clojure.lang.DynamicClassLoader@273f212a #DynamicClassLoader clojure.lang.DynamicClassLoader@4178feba #DynamicClassLoader clojure.lang.DynamicClassLoader@5323961b #DynamicClassLoader clojure.lang.DynamicClassLoader@26a0c73f #DynamicClassLoader clojure.lang.DynamicClassLoader@6f603bdc #DynamicClassLoader clojure.lang.DynamicClassLoader@2f368c5d #DynamicClassLoader clojure.lang.DynamicClassLoader@5b31fd9 #AppClassLoader sun.misc.Launcher$AppClassLoader@4aad3ba4 #ExtClassLoader sun.misc.Launcher$ExtClassLoader@3326b249 *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
Colin Jones trptco...@gmail.com 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
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) #DynamicClassLoader clojure.lang.DynamicClassLoader@26a0c73f #DynamicClassLoader clojure.lang.DynamicClassLoader@6f603bdc #DynamicClassLoader clojure.lang.DynamicClassLoader@2f368c5d #DynamicClassLoader clojure.lang.DynamicClassLoader@5b31fd9 #AppClassLoader sun.misc.Launcher$AppClassLoader@4aad3ba4 #ExtClassLoader sun.misc.Launcher$ExtClassLoader@3326b249 *Top* nil user= 1 1 user= 1 1 user= 1 1 user= 1 1 user= (print-class-loader-stack) #DynamicClassLoader clojure.lang.DynamicClassLoader@5be04861 #DynamicClassLoader clojure.lang.DynamicClassLoader@7481933a #DynamicClassLoader clojure.lang.DynamicClassLoader@273f212a #DynamicClassLoader clojure.lang.DynamicClassLoader@4178feba #DynamicClassLoader clojure.lang.DynamicClassLoader@5323961b #DynamicClassLoader clojure.lang.DynamicClassLoader@26a0c73f #DynamicClassLoader clojure.lang.DynamicClassLoader@6f603bdc #DynamicClassLoader clojure.lang.DynamicClassLoader@2f368c5d #DynamicClassLoader clojure.lang.DynamicClassLoader@5b31fd9 #AppClassLoader sun.misc.Launcher$AppClassLoader@4aad3ba4 #ExtClassLoader sun.misc.Launcher$ExtClassLoader@3326b249 *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