一种可能的方法是将 a 存储WeakReference
到 seq 中,然后在稍后的某个时间点,在应该丢弃对 seq 的所有引用之后,强制进行垃圾回收,取消引用 WeakReference.get
并查看它是否已被清除。例如:
(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's 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))))
但是请注意,在 Java 中测试与垃圾收集和内存分配相关的任何东西都是一门不精确的科学,因为这些东西是由 JVM 异步管理的。特别是,System.gc()
只建议JVM做垃圾回收;无法保证当该方法返回时弱引用将被清除,因此该测试可能会出现虚假失败。出于这个原因,许多风格检查器会将调用标记System.gc()
为“巫毒”。
一般来说,最好的方法是编写可靠的代码,并且只有在很明显存在内存泄漏时才在VisualVM等分析器中进行调试。