One possible way is to save the WeakReference
in seq, and then at some point later, after all the seq links had to be dropped, forced garbage collection, dereferenced WeakReference with .get
and saw that it cleared. For instance:
(let [r (atom nil) s (atom nil)] (let [x (repeat 1000 1)] (reset! r (java.lang.ref.WeakReference. x)) (reset! s (map (partial * 2) x))) ;; the lazy seq created by map has not yet been realized. (is (false? (realized? @s))) ;; Request garbage collection. (System/gc) ;; since it not realized, the result from map still has a reference ;; to the head of its input seq. (is (false? (nil? (.get @r)))) ;; Realize the seq returned from map. (dorun @s) (is (realized? @s)) ;; Request garbage collection again. (System/gc) ;; Once the result from map has been realized, it should discard its reference ;; to the head of the input seq. (is (nil? (.get @r))))
Be careful, however, testing anything related to garbage collection and memory allocation in Java is an inaccurate science because this stuff is managed asynchronously by the JVM. In particular, System.gc()
only assumes that the JVM does garbage collection; There is no guarantee that a weak link will be cleared when this method returns, so this test is prone to false crashes. For this reason, many style checkers will mark System.gc()
calls as "voodoo".
In general, you are best off writing solid code and debugging a profiler, such as VisualVM , only when it becomes apparent that you have a memory leak.
source share