- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在Clojure中编写了一些core.async代码,当我运行它时,它消耗了所有可用内存,并因错误而失败。似乎在core.async管道中使用mapcat
可以消除背压。 (这是不幸的,其原因超出了此问题的范围。)
以下是一些代码,它通过将:x
计数进出mapcat
编码转换器来演示该问题:
(ns mapcat.core
(:require [clojure.core.async :as async]))
(defn test-backpressure [n length]
(let [message (repeat length :x)
input (async/chan)
transform (async/chan 1 (mapcat seq))
output (async/chan)
sent (atom 0)]
(async/pipe input transform)
(async/pipe transform output)
(async/go
(dotimes [_ n]
(async/>! input message)
(swap! sent inc))
(async/close! input))
(async/go-loop [x 0]
(when (= 0 (mod x (/ (* n length) 10)))
(println "in:" (* @sent length) "out:" x))
(when-let [_ (async/<! output)]
(recur (inc x))))))
=> (test-backpressure 1000 10)
in: 10 out: 0
in: 2680 out: 1000
in: 7410 out: 2000
in: 10000 out: 3000 ; Where are the other 7000 characters?
in: 10000 out: 4000
in: 10000 out: 5000
in: 10000 out: 6000
in: 10000 out: 7000
in: 10000 out: 8000
in: 10000 out: 9000
in: 10000 out: 10000
:x
7000。
最佳答案
UPDATE 2020-01-14:现在修复了内存泄漏。
问题“内存泄漏在哪里?”有两种可能的解释。
首先,数据存放在哪里?答案似乎在扩展转换下游的 channel 缓冲区中。
默认情况下, channel 使用FixedBuffer
(clojure.core.async.impl.buffers/FixedBuffer),可以告诉它是否已满,但不反对过度满。
其次,哪段代码会导致缓冲区过满?这(如果我错了,请纠正我)似乎出现在take!
(the ManyToManyChannel
method)的clojure.core.async.impl.channels/ManyToManyChannel中,其中在缓冲区中的first call to add!
发生在发生任何calls to full?
之前。
似乎take!
假定它可以为它删除的每个项目将至少一个项目添加到缓冲区中。对于长时间运行的扩展传感器(例如mapcat
),这并不总是一个安全的假设。
通过在core.async的本地副本中将this line更改为(when (and (.hasNext iter) (not (impl/full? buf)))
,我可以使问题中的代码按预期运行。 (注:我对core.async的理解不足以保证它是您使用案例的可靠解决方案。)
更新2016-09-17:现在有一个问题:http://dev.clojure.org/jira/browse/ASYNC-178
2020年1月14日更新:此问题自https://clojure.atlassian.net/browse/ASYNC-210起已修复(尽管之前的凭单已被关闭为“拒绝”)
关于asynchronous - 当mapcat破坏core.async中的背压时,内存泄漏在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37953401/
我有一个产生惰性序列的函数,称为 a 函数。 如果我运行代码: (map a-function a-sequence-of-values) 它按预期返回一个惰性序列。 但是当我运行代码时: (mapc
我对 Clojure 真的很陌生! `mapcat 如何工作? 最佳答案 mapcat function只是申请concat function的快捷方式结果为 map function : => (m
为了更好地理解mapcat,我举了一个例子: user> (mapcat #(list % %) [1 2 3]) (1 1 2 2 3 3) 并试图重现文档描述的内容,故意使用 map 和 con
在 Clojure 中有一个名为 mapcat 的函数在 Clojure 中,它与 flatmap in Scala 有一些相似之处.是used to map a function to a list
我是一名优秀的程序员,十分优秀!