3

My API is a .Net Core 3.1 and I have an object that can be very large depending on the query filters. The overall time is very fast (about 10 seconds for a 100k rows), but when I send it back to the client, it takes +- 2 minutes.

To return the object, I just return with the Ok method like below:

return Ok(object);

If I try to serialize this object and send the JSON as content, it's fast but I start to get out of memory exception with multiple calls because the memory is not released.

var json = JsonConvert.SerializeObject(object);
return Content(json);

I'm using Newtonsoft.Json, but I have tried the new System.Text.Json too.

Is there any other approach to work with large objects and serialization, or somehow work with the Garbage Collector to release the allocated memory?

Maturano
  • 951
  • 4
  • 15
  • 42
  • Does this answer your question? [Serializing an object using Json.Net causes Out of Memory exception](https://stackoverflow.com/questions/26128376/serializing-an-object-using-json-net-causes-out-of-memory-exception) – Bruno Xavier Jun 19 '20 at 13:38
  • @BrunoXavier That would avoid the out of memory but the time to read and write a File will not help. I have already tried this approach but it takes more time than returning Ok(object) – Maturano Jun 19 '20 at 13:49
  • and I believe paging wouldn't be a viable solution? – Bruno Xavier Jun 19 '20 at 13:56
  • 1) Have you tried profiling the *+- 2 minutes* to see where the problem is? 2) You might try setting `GCSettings.LargeObjectHeapCompactionMode`, see [Why Large Object Heap and why do we care?](https://stackoverflow.com/a/8953503/3744182). – dbc Jun 19 '20 at 14:04
  • @BrunoXavier Yes, paging is a good approach, but for this specific case, I need to return a large Json (or other format maybe) – Maturano Jun 19 '20 at 14:09
  • @dbc 1) It's regarding the Serialization. When I return Ok(object), under the hood, aspnet uses Json.Net (set up in Startup.cs) to serialize the object. So it's a code I can't modify what the framework does (at least I don't know how). 2) I've never worked with that but will take a look – Maturano Jun 19 '20 at 14:17
  • The out of memory exceptions likely occur because the enormous `string` allocated by the call to `JsonConvert.SerializeObject(object)` goes on the large object heap, which is not compacted. You could try compacting it as shown in the link above, which may help, or you could try serializing to a "chunked" memory stream, such as one of the ones from [“Chunked” MemoryStream](https://stackoverflow.com/q/1203121/3744182) or elsewhere, e.g. [`Microsoft.IO.RecyclableMemoryStream`](https://github.com/Microsoft/Microsoft.IO.RecyclableMemoryStream). Then return it using `StreamContent` – dbc Jun 19 '20 at 14:28
  • So you are saying that `Ok(object)` is slow but `JsonConvert.SerializeObject(object)` is fast, despite the fact that `Ok(object)` uses Json.NET underneath? Have you been able to profile that and determine why? And for the out-of-memory exceptions you might be hitting the *effective* [max string length](https://stackoverflow.com/q/140468/3744182) on your system. – dbc Jun 19 '20 at 14:30
  • @dbc I'm using the Diagnostic tools from Visual Studio to check the memory consumption. Regarding the Ok(object), where the framework serializes the object in JSON and returns, I can't answer that, but in my tests (using Fiddler), it takes more time than serializing first and then sending as Content but using this second approach I started to get the memory issues. Somehow the .net framework handles that when using Ok(). I think for this case, the best way to go is using streams as you suggested. – Maturano Jun 19 '20 at 14:58

0 Answers0