Почему фрагментация управляемой кучи влияет на успешность запросов на выделение неуправляемой кучи?

Мне не удалось найти удовлетворительное объяснение того, почему вызов GC.Collect перед большим неуправляемым выделением (в моем случае перед созданием большого (~250 Мб) ресурса DirectX) предотвращает исключение нехватки памяти. Почему сжатие управляемой кучи допускает неуправляемое распределение?

Как процесс.Net разделяет свое адресное пространство между управляемыми и неуправляемыми кучами?

Мое предположение заключается в том, что процесс.Net поддерживает подвижную границу между двумя типами кучи, а GC.Collect позволяет этой границе перемещаться в пользу большей неуправляемой кучи. Что-то вроде этого:

  • (M) ожидаемые отчисления
  • (U) неуправляемые распределения
  • (Свободная память
  • Адресное пространство процесса 0-9

Сценарий № 1 - нет GC.Collect

Собираемся сделать неуправляемое выделение из 3 блоков, управляемая куча фрагментирована:

0123456789
MMFFMFFMFU

"Высокая отметка" управляемой кучи на 7

Выделить 3 неуправляемых блока - не получается! Обратите внимание, что верхняя отметка управляемой кучи не оставляет места для неуправляемого распределения.

Сценарий № 2 - с GC.Collect

Собирается сделать неуправляемое распределение 3 блоков, управляемая куча фрагментирована

0123456789
MMFFMFFMFU

"Высокая отметка" управляемой кучи в 7

Позвоните в GC.Collect

0123456789
MMMMFFFFFU

"Высокая отметка" управляемой кучи на 3

Выделите 3 неуправляемых блока - успешно!

0123456789
MMMMFFUUUU

Это как это работает?

0 ответов

Другие вопросы по тегам