Clojure使用iterate时出现了GC超时限制

3
抱歉,可能有些重复,但我从其他帖子中无法解决这个问题。 我正在尝试运行一个计算密集型的迭代算法。 下一个迭代由函数“update”给出,并通过以下方式收集所有迭代:
(def iterates (doall (take 1000 (iterate update initial-state))))

initial-state是我初始化算法时的零迭代。不幸的是,我无法提供一个最小的例子... update是一个相当复杂的函数,它以地图数据结构作为输入并输出更新后的地图数据结构。代码在总迭代次数达到800以下时运行良好,但对于任何更大的迭代次数则会产生下面的错误。一般意见认为,仅仅增加垃圾回收器可用的空间是不够的,因为这表明存在更深层次的问题(也许)。在其他帖子中,出现的问题非常具体,然而我的update函数非常复杂。那么,我该如何在这里提供的一般性条件下解决这个问题呢?是否有某些工具实用程序可以使用?

  1. Caused by java.lang.OutOfMemoryError GC overhead limit exceeded

           Double.java:  519  java.lang.Double/valueOf
          Numbers.java:  611  clojure.lang.Numbers$DoubleOps/multiply
          Numbers.java:  148  clojure.lang.Numbers/multiply
              core.clj:   21  ssm4clj.core/corr
              core.clj:    6  ssm4clj.core/corr
              core.clj:   42  ssm4clj.core/innovation
              core.clj:   40  ssm4clj.core/innovation
              core.clj: 2522  clojure.core/partial/fn
              core.clj: 2646  clojure.core/map/fn
          LazySeq.java:   40  clojure.lang.LazySeq/sval
          LazySeq.java:   49  clojure.lang.LazySeq/seq
               RT.java:  521  clojure.lang.RT/seq
              core.clj:  137  clojure.core/seq
              core.clj: 2654  clojure.core/map/fn
          LazySeq.java:   40  clojure.lang.LazySeq/sval
          LazySeq.java:   49  clojure.lang.LazySeq/seq
             Cons.java:   39  clojure.lang.Cons/next
               RT.java:  688  clojure.lang.RT/next
              core.clj:   64  clojure.core/next
         protocols.clj:  168  clojure.core.protocols/fn
         protocols.clj:  124  clojure.core.protocols/fn
         protocols.clj:   19  clojure.core.protocols/fn/G
         protocols.clj:   31  clojure.core.protocols/seq-reduce
         protocols.clj:   75  clojure.core.protocols/fn
         protocols.clj:   75  clojure.core.protocols/fn
         protocols.clj:   13  clojure.core.protocols/fn/G
              core.clj: 6545  clojure.core/reduce
              core.clj: 6527  clojure.core/reduce
              core.clj:  347  ssm4clj.core/mean-conditional
              core.clj:  319  ssm4clj.core/mean-conditional
                  REPL:  332  ipp4clj.multiplexing/update-single-gp-mean
                  REPL:  329  ipp4clj.multiplexing/update-single-gp-mean
    

1
一个包含1000个状态的集合需要多少内存?你是否可能没有足够的RAM来容纳这么多数据和计算过程中产生的额外垃圾? - Sam Estep
@SamEstep,当我“top”进程时,问题进程在%MEM列中的百分比大约为30。检查 top 文档,%MEM 显示任务当前使用的可用物理内存份额。据我所知,该进程仅使用了我的 RAM 的 30%。 - Lindon
@ChrisMurphy 很不幸,在这个应用程序中我需要所有的迭代。 - Lindon
1
@Lindon 是的,你说得对;我忘记了JVM内存还有其他限制。30%的RAM相当于多少?你可能需要根据这里的解释增加最大堆大小。但我的问题仍然存在:1000个状态集会占用多少内存?由于您没有指定状态结构和“update”函数,因此我们无法在没有这些信息的情况下做出判断。 - Sam Estep
2
你尝试过使用jvisualvm查看正在运行的JVM进程吗?Oracle JDK中已经包含了它,而OpenJDK通常需要单独安装。 - Stefan Kamphausen
显示剩余4条评论
1个回答

1
为了配合@StefanKamphausen的评论,我认为jvisualvm也会对您有很大帮助。这里是使用方法的步骤介绍。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接