Open frivard-coveo opened 3 days ago
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis See info in area-owners.md if you want to be subscribed.
Why not use array pools for JsonElements?
Where/when would the array be released back to the pool?
It's what Stephen said. There's no point in using array pools unless there is a mechanism for returning used buffers to the pool. JsonDocument
achieves this by implementing IDisposable
but JsonElement
is different and cannot do the same.
Description
My program is looping over a lot of json, and we are encountering a lot of GC pressure. I was digging into the code trying to understand what we are doing wrong. My findings led me to
JsonSerializer.Deserialize<JsonElement>(ref utf8JsonReader, options);
JsonElementConverter
ends up calling https://source.dot.net/#System.Text.Json/System/Text/Json/Document/JsonElement.Parse.cs,49but.. if instead my custom converter returns a 'JsonDocument' (and later on I take its RootElement), the built-in JsonDocumentConverted ends up calling https://source.dot.net/#System.Text.Json/System/Text/Json/Document/JsonDocument.Parse.cs,420
Notice the difference? The main difference here is that
JsonDocumentConverter
path isUseArrayPools=true
, whileJsonElementConverter
path isUseArrayPools=false
, although both of them ask to build a JsonDocument out of the stream.I know a lot of care, lots of reviews, from very clever individuals go into such libraries. I'd just like to know : why ? Why not use array pools for JsonElements? Put it another way: if instead of deserializing to a JsonElement I deserialize to a JsonDocument and take its RootElement, am I exposing myself to memory corruption issues (because of the ArrayPool underneath) ?
Configuration
.NET 8 on both Windows and Linux.
Regression?
No, was like that before.
Analysis
My colleague pointed out that JsonElement is a struct, and JsonDocument a class. However I fail to see the impact on using array pools or not to back the JsonDocument.