Экономим Память с 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