Топ Вопросов о Памяти в .NET. Продолжение 9-12
Начало 1-4
Продолжение 5-8
9. Что обязательно будет содержать дамп памяти любого приложения .NET?
Забавный факт, который иногда может вводить в заблуждение при анализе дампов памяти: каждый процесс .NET заведомо выделяет экземпляры
OutOfMemoryException и StackOverflowException. Просто на случай, если они понадобятся, что будет означать действительную нехватку памяти и отсутствие возможности их создать!Кроме того, некоторые массивы
object[] предварительно выделяются в LOH для ссылок на объекты, используемые «дескрипторами». Это важный механизм, используемый интернированием строк, статикой и локальной статикой потока. Так, например, даже если вы вообще не используете LOH, вы увидите там несколько массивов, ссылающихся на ваши статические объекты.10. Что означает выражение "stop the world" в контексте сборки мусора?
Каждый запуск сборки мусора в .NET имеет несколько коротких и длинных фаз, когда ожидается, что среда выполнения «приостановит» приложение. Эти паузы также известны как фазы «остановки мира» ("stop the world"). И в целом они явно нежелательны, так как влияют на скорость отклика и производительность приложения. Многие улучшения .NET GC делают эти паузы как можно короче.
Итак, «остановка мира» - это пауза на время выполнения сборки мусора (или её части), когда все управляемые потоки «приостановлены». Например, это позволяет получить единообразное представление о том, какие управляемые объекты используются. Неуправляемые потоки не приостанавливаются, поскольку в этом нет необходимости - по умолчанию они не обращаются к управляемым объектам, и даже если это так, они обращаются к «закреплённым» (pinned) объектам, которые обрабатываются особым образом.
11. Как работает параллельная сборка мусора в .NET 5?
Параллельная (фоновая) сборка мусора большую часть времени работает одновременно с управляемыми потоками, не создавая длительных пауз для «остановки мира». Это не означает, что пауз вообще не бывает. Требуется как минимум две паузы: в начале и где-то посередине, чтобы получить некоторое согласованное представление о состоянии памяти.
Более того, текущая реализация .NET GC не может сжимать память во время работы приложения. Таким образом, как полная сборка мусора, так и сборка в поколениях 0 и 1, должны работать в режиме «остановки мира», если требуется сжать память.
Работа над внедрением параллельного сжатия памяти определённо продолжается, и рано или поздно мы можем ожидать его добавления в экосистему .NET. Такие реализации успешно используются, например, в экосистеме JVM. Тем не менее, у них есть свои недостатки и компромиссы, поскольку ничего не даётся бесплатно.
12. Как параметры нужно учитывать, чтобы оценить потребление памяти вашей программой?
Чтобы иметь хорошее общее представление о потреблении памяти вашей .NET-программой, лучше всего знать как минимум три величины.
1. Сколько памяти выделено вашей программе в целом (частные байты - private bytes).
2. Сколько её физически потребляется в RAM («рабочий набор» - working set) - это позволит заметить случаи, когда страницы памяти выгружаются на диск.
3. В контексте .NET полезно знать, сколько памяти потребляется в управляемой куче (Managed Heap).
Что же касается виртуального адресного пространства (virtual address space), оно охватывает всё адресное пространство, которое может использоваться нашим приложением, и не связано напрямую с поведением приложения.
Продолжение следует…
Источник: https://dotnetmemoryexpert.com