From 9081b0dae573987f12654c15f8ed01acbc13870c Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 2 Jun 2020 14:57:43 +0200 Subject: [PATCH] Clear interned stacktraces on plugin unload (IDEA-240458) GitOrigin-RevId: 56943a9f75957079bfce9d3a38498391e344f8dd --- .../src/com/intellij/ide/plugins/DynamicPlugins.kt | 2 ++ .../openapi/util/objectTree/ThrowableInterner.java | 6 ++++++ .../ConcurrentWeakKeySoftValueHashMap.java | 14 ++++++++++---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt b/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt index 6199f7b9d2bd..aa0bea10f0a8 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/DynamicPlugins.kt @@ -43,6 +43,7 @@ import com.intellij.openapi.project.ex.ProjectManagerEx import com.intellij.openapi.project.impl.ProjectImpl import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.IconLoader +import com.intellij.openapi.util.objectTree.ThrowableInterner import com.intellij.openapi.util.registry.Registry import com.intellij.openapi.wm.WindowManager import com.intellij.openapi.wm.impl.ProjectFrameHelper @@ -452,6 +453,7 @@ object DynamicPlugins { // do it after IdeEventQueue.flushQueue() to ensure that Disposer.isDisposed(...) works as expected in flushed tasks. Disposer.clearDisposalTraces() // ensure we don't have references to plugin classes in disposal backtraces + ThrowableInterner.clearInternedBacktraces() IdeaLogger.ourErrorsOccurred = null // ensure we don't have references to plugin classes in exception stacktraces clearTemporaryLostComponent() diff --git a/platform/util/src/com/intellij/openapi/util/objectTree/ThrowableInterner.java b/platform/util/src/com/intellij/openapi/util/objectTree/ThrowableInterner.java index c01a8c0790eb..39a330f6ca96 100644 --- a/platform/util/src/com/intellij/openapi/util/objectTree/ThrowableInterner.java +++ b/platform/util/src/com/intellij/openapi/util/objectTree/ThrowableInterner.java @@ -133,4 +133,10 @@ public class ThrowableInterner { public static Throwable intern(@NotNull Throwable throwable) { return getBacktrace(throwable) == null ? throwable : myTraceInterner.intern(throwable); } + + public static void clearInternedBacktraces() { + for (Throwable t : myTraceInterner.getValues()) { + clearBacktrace(t); + } + } } diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentWeakKeySoftValueHashMap.java b/platform/util/src/com/intellij/util/containers/ConcurrentWeakKeySoftValueHashMap.java index 7fff4c4a44de..e0ef8720bf75 100644 --- a/platform/util/src/com/intellij/util/containers/ConcurrentWeakKeySoftValueHashMap.java +++ b/platform/util/src/com/intellij/util/containers/ConcurrentWeakKeySoftValueHashMap.java @@ -24,9 +24,7 @@ import org.jetbrains.annotations.NotNull; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; -import java.util.Collection; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentMap; /** @@ -294,7 +292,15 @@ public class ConcurrentWeakKeySoftValueHashMap implements ConcurrentMap values() { - throw new UnsupportedOperationException(); + List values = new ArrayList<>(); + processQueues(); + for (ValueReference valueReference : myMap.values()) { + V v = com.intellij.reference.SoftReference.deref(valueReference); + if (v != null) { + values.add(v); + } + } + return values; } @NotNull