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
Remove some GCHandle
s from SendHeaders()
#44561
Remove some GCHandle
s from SendHeaders()
#44561
Conversation
This introduces a new IBufferWriter implementation that manages unmanaged block allocations. The intent here was to remove the allocation of handles amd temporary managed arrays allocations and and replace them with native memory.
SendHeaders()
GCHandle
s from SendHeaders()
/benchmark list |
Crank Pull Request Bot
Benchmarks:
Profiles:
Components:
|
Http.sys isn't in this list. I recently did a perf change to http.sys and had to build locally and run a benchmark. We should add the JSON one. |
an empty Span<>. Zero initialize count member.
Remove use of IBufferWriter<T> and replace with struct with methods for scenarios. Move encoding logic to use Encoding.UTF8 directly.
Plumb UnmanagedBufferAllocator through APIs. Remove many GCHandle allocations. Add UnmanagedBufferAllocator field to ResponseStreamAsyncResult.
always allocate precisely what is needed. Fix an unsafe exception code path.
Remove explicit type static constructor.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
LGTM! |
@davidfowl @Tratcher @JamesNK Please take another look. The CI is all green. |
So, it's a bit slower or a wash and the GC numbers look about the same. 🤔 |
Sharing offline comments I made based on collection of a nettrace for I'm convinced on this change. The logging itself is a win. The number of GCHandle events is staggering. I did a quick experiment locally. Instead of using The nettrace impact is prior to this change the nettrace was 1GB, but after this change it is approximately 40MB. The win here is reduction of the impact of |
@sebastienros I want to assign this to you. Once we have benchmarks running on .NET 8 we should merge this. |
@davidfowl we are tracking net8.0 now (check the charts) so I assume that's what you wanted before we merge the PR. |
Yep |
Could you share what nettrace args are needed to show this? I'm thinking ahead to next year when we write a ASP.NET Core 8 perf improvements blog post and it's useful to have info on the PR so we don't need to figure out how to repro things a year later. |
@BrennanConroy This is easy to see by adding the following arguments to the |
Description
Fixes #40215
This introduces a new type,
UnmanagedBufferAllocator
, that manages unmanaged block allocations. The intent here is to remove the allocation of handles and temporary managed arrays and replace them with native memory.Instead of using an unmanaged memory allocator like
NativeMemory
, theGC.AllocateUninitializedArray()
could be used to create pinned memory. I've rejected this because it puts the onus on the GC to collect the memory whereas with the unmanaged memory it can be freed precisely when it is no longer needed. Since the pinned heap is presently considered only on a gen2 collection it leaves this unused memory around far longer than needed and creates unnecessary pressure.