New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reflection leaks memory #6412
Comments
Imported From: https://issues.scala-lang.org/browse/SI-6412?orig=1
|
@jsuereth said: |
@xeno-by said: |
@xeno-by said (edited on Sep 25, 2012 11:19:53 AM UTC): |
@retronym said: |
Here's a test that shows a leak in import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
object Test {
def main(args: Array[String]): Unit = {
for (i <- 1 to 1024) {
println(i)
val tb = currentMirror.mkToolBox()
val sym = tb.define(q"""object Test { object C { val data = new Array[Byte](16 * 1024 * 1024) }; class C; def main(args: Array[String]) { C.data }}""")
tb.eval(q"""$sym.main(null)""")
tb
}
}
}
The leak is through
Workarounds:
import scala.reflect.runtime.universe
import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
object Test {
def main(args: Array[String]): Unit = {
for (i <- 1 to 1024) {
println(i)
val tb = currentMirror.mkToolBox()
// leaks this toolbox via synthetic "wrapper" packages entered in RootClass!
val sym = tb.define(q"""object Test { object C { val data = new Array[Byte](16 * 1024 * 1024) }; class C; def main(args: Array[String]) { C.data }}""")
tb.eval(q"""$sym.main(null)""")
// workaround
unlinkFromRootOwner(sym)
// This version doesn't leak
// tb.eval(q"""{object Test { object C { val data = new Array[Byte](16 * 1024 * 1024) }; class C; def main(args: Array[String]) { C.data }}; Test.main(null)}""")
}
println("sleeping"); Thread.sleep(120 * 1000)
}
def unlinkFromRootOwner(sym0: Symbol): Unit = {
val symtab = universe.asInstanceOf[scala.reflect.internal.SymbolTable]
val sym = sym0.asInstanceOf[symtab.Symbol]
val symToRemove = sym.ownerChain.dropRight(1).last.sourceModule
val scope = symToRemove.owner.info.decls
scope.asInstanceOf[{def syncLockSynchronized[T](o: => T): T}].syncLockSynchronized {
println(s"unlinking $symToRemove")
scope.unlink(symToRemove)
}
}
}
|
http://groups.google.com/group/scala-internals/browse_thread/thread/bc60a6909accd18d
The text was updated successfully, but these errors were encountered: