From ad9fd7ecf3c03f5cde070de8e033af18676bc578 Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Mon, 15 Feb 2021 18:06:57 +0300 Subject: [PATCH] KotlinBinaryClassCache: clean-up request caches for all threads ^KT-44550 Fixed --- .../load/kotlin/KotlinBinaryClassCache.kt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) 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