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

ArrayMemoryPool.ArrayMemoryPoolBuffer implementation does not dispose if the ref count reaches 0 #25236

Closed
davidfowl opened this issue Feb 28, 2018 · 8 comments
Assignees
Milestone

Comments

@davidfowl
Copy link
Member

Seems like when we ported this from corefxlab we removed a bunch of functionality. Originally the implementation called Dispose on the reference count = 0:

https://github.com/dotnet/corefxlab/blob/c81145ba362ca6649dcf97ae662869f7005061ee/src/System.Buffers.Primitives/System/Buffers/Pooling/ArrayMemoryPool.cs#L91-L97

Now it does nothing.

https://github.com/dotnet/corefx/blob/master/src/System.Memory/src/System/Buffers/ArrayMemoryPool.ArrayMemoryPoolBuffer.cs#L88

This is making pipelines basically leak memory like crazy when using this pool implementation (which is now the default). Can we clarify on the semantics here ASAP?

/cc @stephentoub @KrzysztofCwalina @ahsonkhan @atsushikan

@ghost
Copy link

ghost commented Feb 28, 2018

Seems to me the refcount is about tracking the lifetime of the pinned MemoryHandle and catching cases where you dispose while still using the pinned MemoryHandle, while Dispose is about tracking the lifetime of the underlying storage. If you rent, you're already expected to Dispose or use the using construct whether you create a pinned MemoryHandle or whether you just use it as an array. Saying "don't Dispose" in one case and "do Dispose" in the other doesn't make sense to me.

@davidfowl
Copy link
Member Author

@atsushikan did that change during the port? As you can see that wasn't originally the case but we need to clarify the contract because pipelines is relying on these semantics for correctness. Also our ASP.NET Core SlabMemoryPool implementation does this today https://github.com/aspnet/Common/blob/9d58f3473c558ea67306b0cb09b67c1ccdedf25e/shared/Microsoft.Extensions.Buffers.Sources/MemoryPoolBlock.cs#L102-L112.

@ghost
Copy link

ghost commented Feb 28, 2018

Yes, it did change during the port.

@ghost
Copy link

ghost commented Feb 28, 2018

Right, let's clarify the contract. I've put in my two cents, but let's see what the api guys think.

@KrzysztofCwalina
Copy link
Member

Yeah, ArrayMemoryPoolBuffer is supposed to auto-dispose when refcount drops to zero.

@davidfowl
Copy link
Member Author

I think it's worth having some MemoryPool<T> tests in place that serve as a specification for various implementations. If the semantics are wrong here, there are dire consequences https://github.com/dotnet/corefx/issues/27543#issuecomment-369132611

@joshfree joshfree assigned ghost Mar 7, 2018
@KrzysztofCwalina KrzysztofCwalina assigned GrabYourPitchforks and unassigned ghost Mar 20, 2018
@KrzysztofCwalina
Copy link
Member

@GrabYourPitchforks, once we decide what semantics we want, we will decide who does the work.

@KrzysztofCwalina
Copy link
Member

actually, I noticed this is fixed. So just make sure the semantics are what we want.

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 2.1.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants