-
Notifications
You must be signed in to change notification settings - Fork 1k
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
DirectBufferPool: The buffer is not properly freed in the Release function #5325
Comments
The implementation is correct, its a pool, the released buffer is returned to the pool of buffer by pushing it. |
@Arkatufus where's the implementation code for |
The problem happened precisely because the stack |
Got it. |
There is a big difference between the C# and JVM implementation of DirectBufferPool. In JVM, DirectByteBufferPool is a simple object pool intended as a reference holder to a fixed maximum number on ByteBuffer objects. Its purpose is to prevent the JVM from recreating and garbage collecting ByteBuffer instances over and over again to optimize the speed of Java NIO. It does not care if some code tried to rent more memory or tried to release an instance when it is full, it just creates a new instance or let the system GC any overflows. In C#, we use DirectBufferPool to optimize how memory is allocated and limits the maximum amount of memory of each pool can use. It is actually holding a reference to all the memory it allocated and can be a cause for memory leak if rented buffers are not released, which is what I think happened on this bug report, something is not releasing their byte buffer reference back to the pool correctly. We could probably fix this by removing the memory optimization part of the buffer and just hands out standalone array of bytes instead of trying to hand manage optimized blocks of memory. |
We do have a disabled buffer pool that turns this functionality off - the idea is still good, reducing unnecessary allocations, but we need to find where we aren't returning the memory. My guess is that the failure path is where I would look. |
When I say turning off the memory optimization, I ment the memory block allocation style; we don't have to hold any reference to the allocated memory block that way. We can still do pooling to minimize the cost of memory allocation and GC, they just wont be in contiguous memory blocks. |
Got it. |
Maybe I should create a new class without the memory optimization, lets call it |
I think this already does that @Arkatufus https://github.com/akkadotnet/akka.net/blob/master/src/core/Akka/IO/Buffers/DisabledBufferPool.cs |
The |
Ah I see. I wonder if we can use any of the built-in memory pool types to handle this? I think they ship as separate BCL implementations if you're not using a newer .NET runtime. |
I'm reading up on it, that would need some code changes though. I'll try to make another PR for it. |
Would using the |
@ismaelhamed |
Version Information
Version of Akka.NET? 1.4.25
Which Akka.NET Modules? Akka.IO
Describe the bug
The DirectBufferPool class throws an exception because the buffer is not properly freed in the Release function.
(https://github.com/akkadotnet/akka.net/blob/master/src/core/Akka/IO/Buffers/DirectBufferPool.cs)
Expected behavior
The buffer should be released.
Actual behavior
The buffer is not released and new data is added using the Push function (see screenshots).
Screenshots
Environment
Windows
.NET Framework 4.8
The text was updated successfully, but these errors were encountered: