TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2502 2.86K
День 2070. #ЗаметкиНаПолях
Экономим Память с RecyclableMemoryStream

Когда мы работаем с потоками, у нас могут быть процессы с большой нагрузкой на GC, что означает снижение производительности из-за трат на сборку мусора.

В Microsoft создали библиотеку RecyclableMemoryStream для обеспечения пула для объектов MemoryStream с целью повышения производительности приложения, особенно в области сборки мусора.

Когда мы работаем с большими потоками, библиотека повышает производительность, выделяя объекты в кучу 2-го поколения, что должно сделать сборку мусора менее частой.

Подробно работа RecyclableMemoryStream расписана по ссылке выше, а мы рассмотрим небольшой пример. Представьте, что мы хотим сериализовать и заархивировать большой объект, в нашем случае - большую коллекцию. Чтобы её сгенерировать используем Bogus. Полный код примера можете посмотреть тут. Важно, что коллекция содержит 50000 элементов, и будет иметь всегда одинаковые случайные данные, поскольку используется одно и то же начальное число для их генерации.

Затем мы сериализуем коллекцию в zip-поток. Вот пример с MemoryStream:
List<User> users = PersonGenerator.Generate();

using (var stream = new MemoryStream())
{
using (var gzip = new GZipStream(
stream, CompressionLevel.Optimal, true))
{
await JsonSerializer.SerializeAsync(gzip, users);
await gzip.FlushAsync();
}
}

Теперь сравним с реализацией, использующей RecyclabeMemoryStreamManager:
List<User> users = PersonGenerator.Generate();
var msMgr = new RecyclableMemoryStreamManager();

using (var stream = msMgr.GetStream("memory"))
{
using (var gzip = new GZipStream(
stream, CompressionLevel.Optimal, true))
{
await JsonSerializer.SerializeAsync(gzip, users);
await gzip.FlushAsync();
}
}

Очень похоже, за исключением того, что вместо MemoryStream используется RecyclabeMemoryStreamManager.

Теперь измерим производительность. Генерируем коллекцию и создаём экземпляр RecyclabeMemoryStreamManager в глобальной настройке, измеряем только сериализацию и сжатие.
|       Method |     Mean |   Allocated |
| Recyclable | 496.1 ms | 37.59 KB |
| MemoryStream | 506.2 ms | 16422.09 KB |


Как видите, у RecyclableMemoryStreamManager огромное преимущество в использовании памяти.

RecyclableMemoryStreamManager имеет множество настроек, провайдер EventSource для трекинга, а также хуки событий, куда вы можете добавлять свой код.

Источник: https://medium.com/@matias.paulo84/recyclablememorystream-vs-memorystream-c4aa341324a9
  • 👍 27
More from @netdeveloperdiary
  1. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  2. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  3. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  4. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  5. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  6. Oct 3, 2026Post #3360
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →