Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 为什么我在通道sub/unsub中有以下代码的内存泄漏?_Clojure_Core.async - Fatal编程技术网

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抛出。