tgoop.com/csharp_1001_notes/694
Last Update:
🧠 Задача для .NET разработчиков: «Загадочная утечка памяти в ASP.NET Core приложении»
🧩 Уровень: Senior .NET / Backend Engineer
🎯 Цель: Найти и устранить причину роста памяти без падений и исключений
📍 Ситуация:
У вас — высоконагруженное API на ASP.NET Core (.NET 8), работающее под Linux в контейнере.
Сервис обрабатывает тысячи запросов в минуту. Мониторинг показывает:
- Память растёт стабильно, но не освобождается
- GC работает, но не очищает выделенную память
- dotnet-counters
показывает рост в LOH (Large Object Heap)
- Приложение не падает, но хост начинает свапать и тормозить
- При перезапуске — память очищается, но через 2–3 часа снова заполняется
❗ В логах — тишина, ошибок нет. Библиотеки: Newtonsoft.Json
, HttpClient
, MemoryCache
, EF Core
.
---
🧩 Твоя задача:
1. Почему .NET GC может не освобождать LOH, даже при работе GC?
2. Какие действия вызывают накопление в LOH?
3. Как можно отследить, какие объекты скапливаются в памяти?
4. Чем опасен повторный вызов HttpClient
или StringBuilder
без очистки?
5. Как корректно использовать MemoryCache
, чтобы избежать утечек?
💡 Подсказка:
- Часто виноваты: большие строки, сериализация, `ToString()`,
-
- Частое создание
🧩 Уровень: S
🛠 Решение:
1. Запускаем профилировщик:
dotnet-gcdump collect -p <PID>
dotnet-gcdump analyze dump.gcdump
2. Смотрим типы с самым большим retained size:
List<string>
, byte[]
, MemoryStream
→ В коде — сериализация в JSON огромных объектов без ограничения глубины
3. Находим участок с
JsonConvert.SerializeObject(hugeObject)
без MaxDepth
4. Исправления:
- Добавить настройки сериализации:
new JsonSerializerSettings { MaxDepth = 5, ReferenceLoopHandling = Ignore }
- Ограничить
MemoryCache
по размеру:
new MemoryCache(new MemoryCacheOptions { SizeLimit = 100_000_000 });
- Использовать
HttpClientFactory
вместо new HttpClient()
на каждый запрос5. Альтернатива: перейти на
System.Text.Json
с Utf8JsonWriter
— меньше аллокаций📌 Вывод:
Даже без явных ошибок .NET-приложение может стабильно "утекать" в LOH — через сериализацию, кэш или неправильную работу с потоками. Только анализ дампа памяти и правильная конфигурация GC и кешей помогут найти такие проблемы.
@csharp_1001_notes
BY C# 1001 notes
Share with your friend now:
tgoop.com/csharp_1001_notes/694