Skip to content
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

Using ODataUtf8JsonWriter leads to increased memory usage and latency when writing properties with large string or byte[] values #2845

Closed
habbes opened this issue Jan 24, 2024 · 0 comments · Fixed by #2846
Assignees

Comments

@habbes
Copy link
Contributor

habbes commented Jan 24, 2024

We have customers with scenarios that write payloads with really large string values. For example, string property values with 18 million characters. This causes problems when using ODataUtf8JsonWriter because Utf8JsonWriter.WriteStringValue() will write that entire string to the buffer all at once. Since this exceeds the buffer size, it will allocate a buffer large enough to fit the entire string in memory. If the string needs escaping, it will also allocate a buffer large enough to store the escaped version of the string. This causes issues with large-object heap (LOH) allocations, increase in latency due to increased GC pressure, etc.

image

image

This is a known issue of Utf8JsonWriter. At the time of this writing there's a TODO item in the Utf8JsonWriter source

image

that references the following issue: dotnet/runtime#29293 from 2019. That issue proposes writing large strings in smaller 4KB chunks instead of all at once. That issue seems to have been closed due to inactivity. But there's an other open issue with an active discussion thread and design proposals dotnet/runtime#67337 that seems to have caught some momentum.

Meanwhile, we could solve this in our library by detecting large strings based on some threshold, write to the buffer in chunks and flush it to the stream intermittently before getting to the point where the buffer needs to be resized. Ironically, our default JsonWriter gets this for free by using the TextWriter.

The drawback of doing this ourselves (at least until Utf8JsonWriter supports it), is that we'll have to handle string escaping, and write the separator manually. Luckily, we already dealt with the separator issue when working on raw values: #2527

NOTE: This issue also applies to writing byte[] arrays, and possibly to raw values. I don't think property names and other primitive values present a concern because they tend to be short.

Assemblies affected

Microsoft.OData.Core 7

@habbes habbes changed the title Using ODataUtf8JsonWriter leads to increased memory usage and latency when writing properties with large string values Using ODataUtf8JsonWriter leads to increased memory usage and latency when writing properties with large string or byte[] values Jan 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants