-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix memory leak in MemoryCache #92550
Conversation
`WeakReference<T>.TryGetTarget` apparently returns false in the target object's finalizer. Here is an example demonstrating that: ```cs CreateTest(); GC.Collect(GC.MaxGeneration); GC.WaitForPendingFinalizers(); void CreateTest() => _ = new Test(); class Test { private readonly WeakReference<Test> _wr; public Test() { _wr = new WeakReference<Test>(this); Console.WriteLine(_wr.TryGetTarget(out _)); // True } ~Test() { Console.WriteLine(_wr.TryGetTarget(out _)); // False } } ``` In MemoryCache that would cause the Stats in the _allStats list to never be cleaned out.
Tagging subscribers to this area: @dotnet/area-extensions-caching Issue Details
CreateTest();
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
void CreateTest() => _ = new Test();
class Test
{
private readonly WeakReference<Test> _wr;
public Test()
{
_wr = new WeakReference<Test>(this);
Console.WriteLine(_wr.TryGetTarget(out _)); // True
}
~Test()
{
Console.WriteLine(_wr.TryGetTarget(out _)); // False
}
} In MemoryCache that would cause the Stats in the _allStats list to never be cleaned out.
|
src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you see any downsides to use this aggressive approach on RemoveFromStats
?
It makes the intention a little less clear imo but I don't see any important downsides. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @verdie-g.
WeakReference<T>.TryGetTarget
apparently returns false in the target object's finalizer. Here is an example demonstrating that:In MemoryCache that would cause the Stats in the _allStats list to never be cleaned out.
At the end of this program,
c._allStats.Count == 100
.