Clojure核心缓存Stackoverflow

时间:2016-08-06 22:07:28

标签: clojure lazy-evaluation

以下是此网站的同名问题。

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

(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))

我得到以下内容。我的代码中没有进行任何concat操作。 这是非常可重复的。我在Java 8上使用clojure 1.7。

Caused by: java.lang.StackOverflowError
    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)

1 个答案:

答案 0 :(得分:4)

core.cache正在制造一个经典的懒惰序列错误:将许多惰性序列连接在一起,而不会查看结果。 FIFOCache存储queue of past misses,当缓存中的空间不足时,它会驱逐该队列中最旧的项目。但是,它不使用真正的队列结构,而是使用延迟序列和结尾,结果类似于Recursive function causing a stack overflow中的结果。

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