-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Add missing clearing of pooled arrays #63710
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
base: main
Are you sure you want to change the base?
Conversation
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.
Pull Request Overview
This PR addresses memory leaks by adding proper clearing of pooled arrays before returning them to array pools. When arrays containing references are returned to pools without clearing, the referenced objects cannot be garbage collected, potentially causing memory leaks.
Key changes:
- Adds conditional clearing logic that only clears arrays when they contain reference types or references
- Uses
RuntimeHelpers.IsReferenceOrContainsReferences<T>()
on .NET and falls back totypeof(T).IsPrimitive
check for .NET Framework - Optimizes clearing by only clearing the used portion of arrays when the count is known
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
src/SignalR/common/Shared/JsonUtils.cs | Adds clearing logic with .NET Framework compatibility for generic array pool wrapper |
src/Shared/ValueStringBuilder/ValueListBuilder.cs | Clears used portion of arrays in Dispose and Grow methods |
src/Mvc/Mvc.NewtonsoftJson/src/JsonArrayPool.cs | Adds clearing for JSON array pool implementation |
src/Middleware/OutputCaching/src/RecyclableArrayBufferWriter.cs | Clears arrays in Dispose and resize operations |
src/Middleware/OutputCaching/src/OutputCacheEntryFormatter.cs | Adds explicit clearing for string array when tags exist |
src/Components/Endpoints/src/FormMapping/PrefixResolver.cs | Clears FormKey array before returning to pool |
src/Components/Endpoints/src/FormMapping/Converters/CollectionAdapters/ArrayPoolBufferAdapter.cs | Clears arrays in buffer operations and result conversion |
src/Components/Components/src/NavigationManager.cs | Clears function delegate array after use |
ArrayPool has a return method with an option for clearing arrays. Why not use it instead of clearing before returning? https://learn.microsoft.com/en-us/dotnet/api/system.buffers.arraypool-1.return?view=net-9.0 |
The array pool method would clear the whole array, regardless of how many items are actually non-zero thus potentially more work than needed. With the approach here just the elements are cleared, that are used. But instead doing this on every use, maybe create a helper function for this like the one linked above? |
Yes, that's why. You generally don't want or need to clear the whole array. 🙂 |
Added the |
2f05452
to
3cd9a03
Compare
Add missing clearing of pooled arrays
I found several places where arrays rented from pools are not cleared before returning. Any objects in the pools' arrays cannot be collected by the GC. This might keep objects in the returned arrays longer or, in the worst case, forever alive.
T
is a reference type or contains references.RuntimeHelpers.IsReferenceOrContainsReferences<T>()
is not available there, sotypeof(T).IsPrimitive
is checked instead.