2011-05-20 68 views
2

在我目前的項目中,我們計劃實施特殊的DSL以允許最終用戶進行工作流自定義。我們正在考慮幾種方法來實現它,其中之一就是使用Scala自己編寫的Scala Interpreter(IMain)和DSL。做了一些最初的實驗,我發現下面的簡單程序有內存泄漏並導致完整的堆消耗。這可以通過每次創建新的IMain對象來解決,但是它非常昂貴的操作(時間和內存),因此使用單個解釋器肯定更好。 interpreter.reset方法每次都被調用,但它沒有幫助。定製DSL的Scala解釋器導致內存泄漏?

如果有人有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 
    } 
} 

回答

2

這不是內存泄漏。您在while循環的持續時間中不斷添加新的sort定義,並且自然地,每個排序定義將增加內存使用量。

另請參閱class unload

+0

它看起來不像類加載問題。我調用interpreter.reset方法創建新的類加載器來加載新的定義。 VisualVM顯示未使用的類定義正在被垃圾收集。 – 2011-05-23 10:06:36