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
Memory leak in SynchronizedTypes.uniques #9537
Comments
Imported From: https://issues.scala-lang.org/browse/SI-9537?orig=1 |
@retronym said: Here's the implementation: // we can keep this lock fine-grained, because super.unique just updates the cache
// and, in particular, doesn't call any reflection APIs which makes deadlocks impossible
private lazy val uniqueLock = new Object
private val uniques = mutable.WeakHashMap[Type, jWeakRef[Type]]()
override def unique[T <: Type](tp: T): T = uniqueLock.synchronized {
// we need to have weak uniques for runtime reflection
// because unlike the normal compiler universe, reflective universe isn't organized in runs
// therefore perRunCaches can grow infinitely large
//
// despite that toolbox universes are decorated, toolboxes are compilers,
// i.e. they have their caches cleaned up automatically on per-run basis,
// therefore they should use vanilla uniques, which are faster
if (!isCompilerUniverse) {
val inCache = uniques get tp
val result = if (inCache.isDefined) inCache.get.get else null
if (result ne null) result.asInstanceOf[T]
else {
uniques(tp) = new jWeakRef(tp)
tp
}
} else {
super.unique(tp)
}
} Can you demonstrate the leak in a stronger way than observing the size of this weak map? |
Stefan Jurco (stefan.jurco-at-gmail.com) said: |
@retronym said: This is a pretty fundamental part of the compiler and I can't see a way to change this. These will indeed end up in the uniques cache until GC evicts them. One idea you might be able to try is use this way to find whether a type is a subclass of scala> val optionClass = symbolOf[Option[_]] // just do this once
optionClass: reflect.runtime.universe.TypeSymbol = class Option
scala> typeOf[Option[Any]].baseType(optionClass) != NoType
res3: Boolean = true
scala> typeOf[Tuple1[Any]].baseType(optionClass) != NoType
res4: Boolean = false |
calling
scala.reflect.runtime.universe.typeOf[Option[_]]
creates new instances for each call in
How to reproduce:
The text was updated successfully, but these errors were encountered: