2024 年 Clojure 状态调查 中分享您的想法!

欢迎!请参阅 关于 页面以了解更多有关此内容的信息。

+1
Collections

从 PersistentQueue 中弹出的元素引用不会立即从队列中删除。这可能导致队列实际包含的对象多于它当前包含的更多情况。

这是因为 PersistentQueue 是通过两个 PersistentVectors 实现的,一个用于头部,一个用于尾部。一旦头部为空,尾部向量将转换为 ChunkedSeq(通过对其进行调用 seq)并放入头部。然而,即使它通过 {{next}} 缩小,ChunkedSeq 也总是保留对起始向量的引用。

示例,使用 clj-memory-meter

`
(require '[clj-memory-meter.core :as mm])

(def q clojure.lang.PersistentQueue/EMPTY)
(def strs (repeatedly 100000 #(String. (.toCharArray "Hello"))))

;; Queue with 100k strings "Hello"
(mm/measure (into q strs))
=> "5.9 MB"

;; Shrink such queue to just 1 element
(nth (iterate pop (into q strs)) 99999)
=> ;; a queue of one element

;; But it still occupies 6 mb
(mm/measure (nth (iterate pop (into q strs)) 99999))
=> "5.9 MB"
`

或许,如果这种行为是预期的,它至少应该反映在文档中?既然 PQ 已经是隐藏的,且文档不足。

2 答案

0

评论由:alexyakushev 创建

编辑:将优先级更改为次要,因为这不是经典的内存泄漏(队列不会无限增长,最大的泄漏是 {{conj}} 当前的最长的 {{pop}} 队列)。

0
引用:[https://clojure.atlassian.net/browse/CLJ-2397](https://clojure.atlassian.net/browse/CLJ-2397)(alexyakushev 报告)
...