Ответ 1
"Память" - это недостаточно точный термин для операционной системы с виртуальной памятью по запросу, такой как Windows, Linux, MacOS. CLR отображает сборку в адресное пространство процесса, используя файл с отображением в памяти (MMF). Просто числа для процессора, по одному на каждые 4096 байт. Пока что из файла ничего не читается.
Это задерживается до тех пор, пока программа не попытается прочитать с адреса внутри адресного пространства. При первом доступе генерируется ошибка страницы, ядро выделяет ОЗУ для страницы и заполняет ее содержимым файла. После чего программа возобновляется, как будто ничего не произошло. Сильно расширяет возможности виртуальной памяти "вы не платите за то, что не используете".
Здесь нет "извлечения", вы читаете данные ресурса непосредственно из памяти, наиболее эффективным способом, которым это могло бы быть реализовано. Внедренный ресурс не ведет себя иначе, чем другие данные в файле, такие как метаданные и MSIL. Вы также не платите ни за какой код в сборке, которую вы никогда не вызываете.
Имейте в виду, что встроенный ресурс занимает тот же ресурс, что и куча GC, он также требует адресного пространства. Единственное реальное отличие состоит в том, что адресное пространство кучи GC поддерживается файлом подкачки ОС и никогда не может использоваться другими процессами, данные сборки поддерживаются файлом сборки и могут использоваться совместно. Большие ресурсы значительно сокращают объем памяти, который вы можете выделить в программе .NET, даже если вы никогда не используете их. Это имеет значение только в 32-битном процессе, 64-битный процесс имеет много терабайт адресного пространства.
Другое ограничение заключается в том, что представление MMF никогда не может превышать 2 ГБ, даже в 64-разрядном процессе, который устанавливает жесткий верхний предел максимального размера ресурса. Обычно это происходит очень рано, что приводит к сбою сборки с CS1566: "Указанный аргумент вышел за пределы допустимых значений". Не очень хорошая диагностика, кстати.