【问题标题】:Scala Interpreter for custom DSL leads to memory leaks?自定义 DSL 的 Scala 解释器导致内存泄漏?
【发布时间】:2011-05-20 16:54:56
【问题描述】:

在我当前的项目中,我们计划实施特殊的 DSL 以允许最终用户进行工作流程自定义。我们正在考虑几种方法来做到这一点,其中之一是使用 Scala 解释器(IMain)和用 Scala 本身编写的 DSL。做一些初步实验,我发现遵循简单的程序会导致内存泄漏并导致堆满消耗。它可以通过每次创建新的 IMain 对象来解决,但这是非常昂贵的操作(时间和内存),所以使用单个解释器肯定更好。每次都会调用interpreter.reset 方法,但没有帮助。

如果有人使用过 Scala Interpreter,您能告诉我如何正确使用它并避免内存泄漏吗?

我们使用的是 Scala 2.9。

import scala.tools.nsc.interpreter._
import scala.tools.nsc.Settings
import java.util.concurrent.TimeUnit

object DslTest {
    val settings = new Settings()
    settings.usejavacp.value = true

    var interpreter = new IMain(settings);

    def main(args : Array[String]) {
        val t = System.currentTimeMillis
        do {
            test()
        } while (System.currentTimeMillis - t < TimeUnit.SECONDS.toMillis(3000))
    }

    def test() {
        interpreter.interpret("""
            def sort(a:Array[Int]): Array[Int] =
                if (a.length < 2) a
                else {
                    val pivot = a(a.length / 2)
                    sort (a filter (pivot>)) ++
                         (a filter (pivot == )) ++
                    sort (a filter(pivot <))
            }""");
        interpreter.reset
    }
}

【问题讨论】:

    标签: scala memory-leaks interpreter dsl


    【解决方案1】:

    这不是内存泄漏。在 while 循环期间,您会不断添加新的 sort 定义,自然,每个排序定义都会增加内存使用量。

    另见class unload

    【讨论】:

    • 看起来不像是类加载问题。我正在调用interpreter.reset 方法来创建新的类加载器来加载新的定义。 VisualVM 显示未使用的类定义正在被垃圾收集。
    猜你喜欢
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多