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

欢迎!有关如何使用该功能的更多信息,请参阅关于页面。

+8
core.async
以下代码将导致OOME


(require '[clojure.core.async :refer [chan close! <! pub sub unsub go timeout]])

(def p* (chan))

(def p (pub p* :topic))

(go
  (loop []
    (let [s (chan)
          t (rand-int Integer/MAX_VALUE)]
     (sub p t s)
     (<! (timeout 10))
     (unsub p t s)
     (close! s)
      (recur))))


(它慢慢增长:要在合理的时间内看到OOME,要么给JVM非常小的内存如64m,要么移除超时步骤。)
问题

我试图分析代码,原因似乎是由于尽管我
从端口取消订阅了通道,但某些东西仍然保留,导致
堆被用完。

6 个答案

0

评论由:amadeoh 提出

这是问题

https://github.com/clojure/core.async/blob/96de9a47ac511d9bb4309645a3bc594a2fc0c33a/src/main/clojure/clojure/core/async.clj#L826-L828

当调用unsub*时,它会只是从指定的主题的mult中取消订阅通道。即使mult没有剩余的taps,mult仍然保留在名为mults的原子中。

我想不出一个干净的解决方案来解决这个问题,因为目前监听mult的通道并没有暴露出来,也就是说,我们目前没有任何办法知道一个mult是否有taps。

0

评论由:gshayban 提出

我也想不出一个干净的处理办法,因为多个订阅者不公开它们的注册者。(在并发系统中的“当前”概念是微妙的)
除了说(也许修改一下文档字符串)这些pub确实是资源外,它们的足迹随着已看到主题的数量而增长,并且资源几乎总是应该受限制。

0

评论者:[email protected]

这也在 https://github.com/apa512/clj-rethinkdb/issues/97 中困扰了我们。我对文档字符串增加的建议是

pubs是资源,它们的足迹随着已看到主题的数量增长。unpub不会回收这部分资源。你不应该用pub订阅无数的主题。

有什么修改/建议吗?您希望我为此创建补丁吗?

0

评论者:[email protected]

pub在没有使用时是否能被垃圾回收?在我进行一些有限的测试时,这似乎不行,但我可能错了。

0

评论者:[email protected]

一个部分的解决方案(我认为?)是使用

如果你知道你不再需要这个主题。

0
参考:https://clojure.atlassian.net/browse/ASYNC-90 (由 alex+import汇报)
...