Clojure 为什么我在通道sub/unsub中有以下代码的内存泄漏?
我正在使用Clojure 为什么我在通道sub/unsub中有以下代码的内存泄漏?,clojure,core.async,Clojure,Core.async,我正在使用[org.clojure/clojure“1.10.1”]、[org.clojure/core.async“1.2.603”和最新的Amazon Corretto 11 JVM(如果与它们有关的话) 以下代码是生产中使用的代码的简化版本,它确实会导致内存泄漏。我不知道为什么会发生这种情况,但我怀疑这可能是由于地下/不明嫌犯的渠道。有人能帮我指出我的代码哪里可能出错,或者我如何修复内存泄漏吗 (ns test-gc.core (:require[clojure.core.async:as
[org.clojure/clojure“1.10.1”]、[org.clojure/core.async“1.2.603”
和最新的Amazon Corretto 11 JVM(如果与它们有关的话)
以下代码是生产中使用的代码的简化版本,它确实会导致内存泄漏。我不知道为什么会发生这种情况,但我怀疑这可能是由于地下/不明嫌犯的渠道。有人能帮我指出我的代码哪里可能出错,或者我如何修复内存泄漏吗
(ns test-gc.core
(:require[clojure.core.async:as a:引用[chan put!close!!go循环超时])
(:import[java.util UUID]))
(def全局消息通道(通道(a/滑动缓冲器200)))
(def全局消息发布(a/pub全局消息目录:id))
(定义承诺[]
(let[id(UUID/randomuid)
总经理(陈)]
(a/次全局消息发布id ch)
[id(go
(let[x(!全局消息ch cmd)
(println(
快速堆转储提供以下统计信息,例如:
- 按实例数分类
java.util.LinkedList
5157128(14.4%)
java.util.concurrent.AtomicReference
3698382(10.3%)
clojure.lang.Atom
3094279(8.6%)
- 按实例大小分类
java.lang.Object[]
210061752 B(13.8%)
java.util.LinkedList
206285120 B(13.6%)
clojure.lang.Atom
148525392 B(9.8%)
clojure.core.async.impl.channels.ManyToManyChannel
132022336 B(8.7%)
我终于找到了原因。通过查看源代码,我们得到了以下部分:
(defn pub)
“创建并返回所提供频道的发布,…”
...
(让[mults(atom{});;主题->mult
确保多(fn[主题]
(或(获取@mults主题)
(换)骡子
#(如果(%topic)%(关联%topic(mult)(chan(buf-fn-topic‘‘‘‘)’)
(主题)
p(具体化
多路复用器
(muxch*[[uuch]ch)
酒吧
(子*[p主题ch关闭?]
(让[m(确保多主题)]
(轻触m通道关闭?)
(不明嫌犯*[p主题ch]
(当让[m(获取@mults主题)]
(联柬权力机构)
(unsub all*[[uuuz](重置!mults{}))
(unsub all*[[主题](交换!mults dissoc主题))]
...
p) ))
我们可以看到mults
存储所有主题
,因此如果我们不清除它,它将单调增加。我们可以添加类似(a/unsub all*global msg pub pid)的内容
来解决这个问题。这段代码的目的是什么?@AlanThompson我承认这是一个糟糕的代码/设计。但主要目的是处理API调用的异步响应。客户端的请求被分发到几个模块,当所有模块都完成后,一条包含额外数据的完成消息被发送到全局消息ch
,然后重新发送为每个请求尝试(正如您可能猜到的,每个请求都用UUID
)标记。您有什么类型的内存泄漏?您能粘贴内存不足异常吗?@rcatellcastell它只是说异常:java.lang.OutOfMemoryError从线程“async-dispatch-1”中的UncaughtExceptionHandler抛出。