Is it safe to cache any PSI element if I use PsiModificationTracker.MODIFICATION_COUNT 关注
Hi,
I am curious is it safe to cache project-wide PSI elements if I use PsiModificationTracker.MODIFICATION_COUNT. If I try to cache a PSI element from another file, I get the following error:
... is retaining PSI, causing memory leaks and possible invalid element access.
The code looks like this:
val key = Key<CachedValue<FormPropertyArray<T>?>>("solar.element.array.$requiredPropertyName")
return CachedValuesManager.getCachedValue(this, key) {
val arrayElement = if(requiredPropertyName == name)
FormPropertyArray(this, valueArray, contentsClass)
else
null
CachedValueProvider.Result(
arrayElement,
PsiModificationTracker.MODIFICATION_COUNT
)
}
, where valueArray is a JsonArray (which is causing the problem).
I did a workaround by not caching it directly but reevaluating in FormPropertyArray one more time. I actually cache a lot of project-wide PSI in my project and never experienced any problems while using MODIFICATION_COUNT tracker. I know that this is a memory-hungry approach, but it is still better than searching and traversing multiple JSON files every time to find the required element.
So, do I need to care about this error and stop caching PSI, or can I just ignore that?
There is a link to repository with code, if it helps.
请先登录再写评论。
Hi,
Could you please share the full error stacktrace and message, so we can better understand the case?
Of course, here it is:
Hi,
Indeed, it seems that you capture
valueArray
PSI element besides the element you cache a value for. If you compute a value for a PSI element, you shouldn’t use other PSI elements in the provider code (lambda passed toCachedValuesManager.getCachedValue()
).See the Javadoc of the
com.intellij.psi.util.CachedValue
class, especially “Context-independence” part.