3

我在运行使用 eval 的遗传编程算法时遇到了这个问题。

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

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

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

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

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

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

编辑: 我添加了一个visualVM的屏幕截图来显示行为,当JVM挂起时,图表不再更新,它继续使用完整的CPU核心。

在此处输入图像描述

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

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

编辑:

仅当我从 leinigen-REPL 使用 eclipse-逆时针运行它时才会出现问题。如果我从基本命令行 REPL 运行代码,则不会出现问题!

4

2 回答 2

0

我注意到上面的例子中内存消耗在稳步增加。添加系统/gc

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

CPU 消耗翻倍,但内存使用量保持在看起来像长期稳定的状态。

于 2016-09-16T23:50:19.677 回答
0

我得出结论,这个问题与 clojure eval 或 JVM 没有直接关系。它仅与 eclipse-逆时针和/或 leiningen-REPL 结合使用。

于 2016-09-17T14:20:04.713 回答