Clojure 核心缓存 Stackoverflow

Clojure Core Cache Stackoverflow

这是一个与此网站同名的问题。

为什么这段代码会在Clojure中抛出Whosebug异常?

(require [clojure.core.cache :as cache])

(def C (atom (cache/fifo-cache-factory {} :threshold 1E7)))

(doseq [i (range 1 1E6)]
  (swap! C cache/miss i i))

我得到以下信息。我没有在我的代码中做任何连接操作。 这是非常可重现的。我在 Java 8.

上使用 clojure 1.7
Caused by: java.lang.WhosebugError
    at clojure.lang.RT.seq(RT.java:507)
    at clojure.core$seq__4128.invoke(core.clj:137)
    at clojure.core$concat$fn__4215.invoke(core.clj:691)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:507)
    at clojure.core$seq__4128.invoke(core.clj:137)
    at clojure.core$concat$fn__4215.invoke(core.clj:691)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:507)

...........
...........
    at clojure.core$concat$fn__4215.invoke(core.clj:691)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:507)
    at clojure.core$seq__4128.invoke(core.clj:137)
    at clojure.core$concat$fn__4215.invoke(core.clj:691)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:507)
    at clojure.core$seq__4128.invoke(core.clj:137)
    at clojure.core$concat$fn__4215.invoke(core.clj:691)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:507)
    at clojure.core$seq__4128.invoke(core.clj:137)
    at clojure.core$concat$fn__4215.invoke(core.clj:691)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:507)
    at clojure.core$seq__4128.invoke(core.clj:137)
    at clojure.core$concat$fn__4215.invoke(core.clj:691)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)

core.cache 犯了一个典型的惰性序列错误:将许多惰性序列连接在一起而不看结果。 FIFOCache 存储一个 queue of past misses, and when it runs out of space in the cache, it evicts the oldest item in that queue. However, instead of using a real queue structure for this, it uses a lazy sequence and concats to the end, with results similar to those in, for example, Recursive function causing a stack overflow.

我会说这是 core.cache 中的错误;您可以针对 its JIRA 提出问题,或者通过不使用如此大的 FIFO 缓存来解决它:它可能会达到几千个左右的大小。