-
Notifications
You must be signed in to change notification settings - Fork 22
Closed
Description
We found a memory leak after upgrading from Scala 2.12.8 to Scala 2.12.10. After investigation,
we realized that the root cause is scala/scala#8112 and confirmed disabling this cache can stop the memory leak.
After digging into codes, we think there are two issues here :
- It caches
TypeTagImplusing thetypeCreator's class. However, the class oftypeCreatorcan be the same when there are multipleJavaMirrors. Hence, the cache may return aTypeTagImplthat ties to an incorrectJavaMirror(It's cached by a previousJavaMirror). TypeTagImplhas a strong reference totypeTagCache(TypeTagImpl->JavaMirror->typeTagCache->java.lang.ClassValue.Identity). Asjava.lang.ClassValue.Identityis the key type andTypeTagImplis the value type ofWeakHashMap(insideClassValue), the current pattern is exactlyWeakHashMap's doc asks to not do:Thus care should be taken to ensure that value objects do not strongly refer to their own keys, either directly or indirectly, since that will prevent the keys from being discarded.
Right now, as long astypeCreator's class and itsClassValueMap(WeakHashMap) is not GCed,TypeTagImplandJavaMirrorwill not be GCed even if there is no other place using them. AstypeCreator's class can be loaded by the root class loader (e.g., it's inside a jar on the classpath), if we cache aTypeTagImplwith suchTypeCreator,TypeTagImplandJavaMirrorwill never be GCed.
Thanks @rednaxelafx for helping me debug this issue.
Reactions are currently unavailable