Clojure eval导致垃圾收集器挂起

时间:2016-09-16 21:00:18

标签: clojure garbage-collection eval metaspace

运行使用eval的遗传编程算法时遇到此问题。

为了说明问题,我将其缩小到以下代码片段:

(loop []
  (do 
    (eval (list '+ (rand) (rand)))
    (recur)))

当我运行代码时,垃圾收集器从元空间卸载所有已创建的$ eval_n类,但在第二个垃圾收集器调用中它会挂起。

我将jdk1.8.0_102与以下JVM选项一起使用: -XX:MetaspaceSize =200米 -XX:MaxMetaspaceSize =200米

过了一会儿,我收到以下错误:

CompilerException java.lang.OutOfMemoryError: Metaspace, compiling:(form-init2581690491924993906.clj:1:1) 

修改 我添加了一个visualVM截图来显示行为,当JVM挂起时,图形不再更新,并且它继续使用完整的CPU核心。

enter image description here

我也尝试使用java 7(没有任何JMV选项),我遇到了与PermGen相同的问题。

任何想法如何避免这个问题?

修改

问题只发生在我使用eclipse-counterclockwise从leinigen-REPL运行它时。如果我从基本命令行REPL运行代码,则不会发生问题!

2 个答案:

答案 0 :(得分:0)

我注意到上面的例子,内存消耗不断增加。添加系统/ gc

(loop [] (do (eval (list '+ (rand) (rand))) (System/gc)) (recur))

将CPU消耗增加一倍,但将内存使用量保持在长期稳定状态。

答案 1 :(得分:0)

我总结说这个问题与clojure eval或JVM没有直接关系。它只与eclipse-counterclockwise和/或leiningen-REPL结合使用。