Make array rental return after TryReadPlpUnicodeChars unconditional #2121
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
fixes #2120
In PR #1866 I introduced the ability for TryReadPlpUnicodeChars to use rented buffers to store the intermediate char[]'s that are needed before a string can be created. That change works well in sync calls but has a problem in async calls.
When used in async mode with a string that spans multiple packets the async replay mechanism causes the TryReadPlpUnicodeChars to be called repeatedly until it has all the data available in the buffered packets. An oversight in the method means that in the fail case a rented buffer is dropped to the GC. The rented buffers' size converge on the size of the requested string which means that as more packets are buffered into the snapshot larger and larger arrays will be allocated through the arraypool and then not returned.
This leads to performance which is no better than using newly allocated arrays and which contributes GC pressure (through the arrays it is dropping being on the LOH) leading to Gen2 GC which causes arraypools to be cleaned up which works against the use of rented buffers.
This change causes the caller of TryReadPlpUnicodeChars to return the rented array on failed paths as well as successful ones.
The test program is derived from the one provided in the issue. It uses the profiler api to get accurate results for small periods where trying to manually getting time snapshot would be error prone:
before this change:
after:
The GC time and run frequency are vastly reduced. This makes the overall repro faster.
The change is very simple. The difficulty was in finding and understanding it.
/cc @Havunen , @roji