diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/KotlinBinaryClassCache.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/KotlinBinaryClassCache.kt index 005b2f236a1..1ec5289d942 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/KotlinBinaryClassCache.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/KotlinBinaryClassCache.kt @@ -23,6 +23,7 @@ import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.util.Computable import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiJavaModule +import java.util.concurrent.CopyOnWriteArrayList class KotlinBinaryClassCache : Disposable { private class RequestCache { @@ -43,17 +44,22 @@ class KotlinBinaryClassCache : Disposable { } private val cache = object : ThreadLocal() { + private val requestCaches = CopyOnWriteArrayList() + override fun initialValue(): RequestCache { - return RequestCache() + return RequestCache().also { requestCaches.add(it) } + } + + override fun remove() { + for (cache in requestCaches) { + cache.result = null + cache.virtualFile = null + } + super.remove() } } override fun dispose() { - cache.get().apply { - result = null - virtualFile = null - } - // This is only relevant for tests. We create a new instance of Application for each test, and so a new instance of this service is // also created for each test. However all tests share the same event dispatch thread, which would collect all instances of this // thread-local if they're not removed properly. Each instance would transitively retain VFS resulting in OutOfMemoryError