-
Notifications
You must be signed in to change notification settings - Fork 923
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
Always use ArrayPool.Shared for optimized use of buffers in buffer manager #2224
Conversation
marcschier
commented
Jul 13, 2023
- The suggestion from .net team is to use shared pool if you have < 1mb buffers you need.
- We now share buffers across connections which is far more efficient when many channels are created and closed.
- There should never be buffers > 64k per spec. But for the memory tracking I have left the old code.
- Open issue. There is no need to lock (pin?) the memory so this was removed because it added 1 additional byte and then you always allocated far larger buffers (likely 128k) for every 64k you wanted. The tracking code is still the same.
… pressure situations and is the better choice for both server and client.
It was remarked that Buffer manager is only created once. That is correct for server, but for client it is created every channel (so twice for every session establishment). Also, please see the documentation on ArrayPool, if you try to rent a buffer that is larger than the max configured (64k + 1) then it always allocates a fresh buffer. If you return this buffer, it is likely not added to a bucket as there is none. Even if that is working on one version of .net it might be different on another. Finally, even if you were to leave the code as is and increase the buffer size by 1 the allocated buffers in the pool will likely be the next highest bucket size, which is very wasteful. What is worse, this probably pushes all these allocations into LOH (> 85k) which is not good. |
@marcschier agree for perf reason to use the shared version, but please bring the cookies back... |
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.
see comments..
m_arrayPool = maxBufferSize <= 1024 * 1024 | ||
? ArrayPool<byte>.Shared | ||
: ArrayPool<byte>.Create(maxBufferSize, 32); | ||
#if TRACK_MEMORY |
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.
use maxArrayLength, bring cookie back etc. Its needed for runtime check of buffer usage.
.shared has a couple of advantages: |
just as a sidenote, the existing code uses 65535 size buffers and ands 1 byte cookie, so the allocations are still in the 64k bucket. |
…nager (OPCFoundation#2224) * The suggestion from .net team is to use shared pool if you have < 1mb buffers you need. * We now share buffers across connections which is far more efficient when many channels are created and closed.