IJPL-166213 use soft references for iconCache in IconDeferrerImpl

If someone reads code for long enough, hard-referenced cache eventually gets too big.
For some reason, `LowMemoryWatcher.register(::clearCache)` does not help with that.
So, let's use soft references instead

GitOrigin-RevId: d9be28c5150161a98cceea6a11bb3adab1d9d41e
This commit is contained in:
Max Medvedev
2024-11-25 16:44:07 +00:00
committed by intellij-monorepo-bot
parent 2c9f176603
commit ea4a8a7f6d
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:Suppress("ReplaceGetOrSet", "ReplacePutWithAssignment")
package com.intellij.ui
@@ -12,11 +12,11 @@ import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.newvfs.BulkFileListener
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.CollectionFactory
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.asContextElement
import kotlinx.coroutines.job
import kotlinx.coroutines.withContext
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.LongAdder
import javax.swing.Icon
@@ -39,9 +39,8 @@ internal class IconDeferrerImpl(coroutineScope: CoroutineScope) : IconDeferrer()
// Due to a critical bug (https://youtrack.jetbrains.com/issue/IDEA-320644/Improve-Smart-PSI-pointer-equals-implementation),
// we are not using "caffeine".
// Furthermore, a size-bounded cache is unnecessary for us because our application has frequent cache clearances,
// such as during PSI modifications.
private val iconCache = ConcurrentHashMap<Any, Icon>()
private val iconCache = CollectionFactory.createSoftKeySoftValueMap<Any, Icon>()
@Volatile
private var mightBePopulated = false // used to avoid multiple calls PHM#clear() which might be expensive, no need to be atomic or something else
private val lastClearTimestamp = LongAdder()