Skip to content
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

[release/2.1] Memory Leak in Microsoft.Extensions.Caching.Memory when handling exceptions #3536

Merged
merged 12 commits into from
Sep 18, 2020

Conversation

wtgodbe
Copy link
Member

@wtgodbe wtgodbe commented Sep 17, 2020

Resolves #3533

Backport of dotnet/runtime#42355

When an exception is thrown inside MemoryCache.GetOrCreate, we are leaking CacheEntry objects. This is because they are not being Disposed properly, and the async local CacheEntryStack is growing indefinitely.

The fix is to ensure the CacheEntry objects are disposed correctly. In order to do this, I set a flag to indicate whether the CacheEntry.Value has been set. If it hasn't, Disposing the CacheEntry won't add it to the cache.

@wtgodbe
Copy link
Member Author

wtgodbe commented Sep 17, 2020

[xUnit.net 00:00:07.62] Microsoft.Extensions.Caching.Memory.MemoryCacheSetAndRemoveTests.GetOrCreate_WillNotCreateEmptyValue_WhenFactoryThrows [FAIL]
Failed Microsoft.Extensions.Caching.Memory.MemoryCacheSetAndRemoveTests.GetOrCreate_WillNotCreateEmptyValue_WhenFactoryThrows
Error Message:
Assert.Null() Failure
Expected: (null)
Actual: CacheEntry { AbsoluteExpiration = null, AbsoluteExpirationRelativeToNow = null, ExpirationTokens = [], Key = "myKey", PostEvictionCallbacks = [], ... }
Stack Trace:
at Microsoft.Extensions.Caching.Memory.MemoryCacheSetAndRemoveTests.GetOrCreate_WillNotCreateEmptyValue_WhenFactoryThrows() in /_/src/Caching/Memory/test/MemoryCacheSetAndRemoveTests.cs:line 169

@dougbu
Copy link
Member

dougbu commented Sep 17, 2020

Ask mode❔

@wtgodbe
Copy link
Member Author

wtgodbe commented Sep 17, 2020

Ask mode❔

Yep, going to send one email w/ all 3 PRs once they're all green & approved (as well as adding the label)

@wtgodbe
Copy link
Member Author

wtgodbe commented Sep 17, 2020

@Tratcher compiler doesn't like the shorter using syntax here, maybe 2.1 isn't on C# 8 yet

/home/vsts/work/1/s/src/Caching/Abstractions/src/MemoryCacheExtensions.cs(38,19): error CS1003: Syntax error, '(' expected [/home/vsts/work/1/s/src/Caching/Abstractions/src/Microsoft.Extensions.Caching.Abstractions.csproj]


internal DateTimeOffset LastAccessed { get; set; }

internal EvictionReason EvictionReason { get; private set; }

public void Dispose()
{
if (!ValueHasBeenSet)
Copy link

@pranavkm pranavkm Sep 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should _scope be Disposed in this case? It's intiialized in the ctor?

@wtgodbe
Copy link
Member Author

wtgodbe commented Sep 17, 2020

@eerhardt @Tratcher GetOrCreate_WillNotCreateEmptyValue_WhenFactoryThrows has been failing constantly in this branch, but not the 3.1 PR: #3536 (comment). Any idea why?

@eerhardt
Copy link
Member

has been failing constantly in this branch, but not the 3.1 PR: #3536 (comment). Any idea why?

looking.

@@ -13,6 +13,7 @@
</PropertyGroup>
<PropertyGroup Condition=" '$(VersionPrefix)' == '2.1.23' ">
<PackagesInPatch>
Microsoft.Extensions.Caching.Memory;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are editing the Caching.Abstractions library as well. Do we need to add it to this list?

@eerhardt
Copy link
Member

eerhardt commented Sep 17, 2020

has been failing constantly in this branch, but not the 3.1 PR: #3536 (comment). Any idea why?

On my machine, the test is failing because Microsoft.Extensions.Caching.Abstractions is being loaded from the 2.1.2 version on NuGet, and not what is being built locally. And since we aren't loading the local version, the fix is not in 2.1.2.

@wtgodbe
Copy link
Member Author

wtgodbe commented Sep 17, 2020

On my machine, the test is failing because Microsoft.Extensions.Caching.Abstractions is being loaded from the 2.1.2 version on NuGet, and not what is being built locally. And since we aren't loading the local version, the fix is not in 2.1.2.

Ahhh, that'd do it. Will try fixing up PatchConfig

@Tratcher
Copy link
Member

You also probably need to add a direct reference from the test project to the Abstractions project. 2.1 doesn't lift transitive references.

@JunTaoLuo
Copy link

There has been some changes in the original PR, please make sure this PR is updated with those changes.

@wtgodbe
Copy link
Member Author

wtgodbe commented Sep 17, 2020

There has been some changes in the original PR, please make sure this PR is updated with those changes.

Believe I now have everything except the shorter syntax for using, which the compiler in 3.1/2.1 doesn't know about

@KalleOlaviNiemitalo
Copy link

This PR does not have dotnet/runtime@72d5741 yet.

@wtgodbe
Copy link
Member Author

wtgodbe commented Sep 18, 2020

This PR does not have dotnet/runtime@72d5741 yet.

I just brought it in

@wtgodbe wtgodbe merged commit dc1dab7 into release/2.1 Sep 18, 2020
@wtgodbe wtgodbe deleted the wtgodbe/MemLeak21 branch September 18, 2020 18:53
JunTaoLuo pushed a commit to dotnet/aspnetcore that referenced this pull request Nov 17, 2020
… handling exceptions (dotnet/extensions#3536)

* Memory Leak in Microsoft.Extensions.Caching.Memory when handling exceptions

* Update patchConfig.props

* Try standardizing use of SetValue

* Apply feedback

* Fix syntax

* Undo breaking change

* Feedback

* Fixup

* Fixup patchConfig

* Add direct ref

* Fix another memory leak when one cache depends on another cache

* Fixup\n\nCommit migrated from dotnet/extensions@dc1dab7
@dougbu dougbu added this to the 2.1.x milestone Apr 5, 2022
@ghost ghost locked as resolved and limited conversation to collaborators May 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants