Отказ от ресурса DLL после его использования

Я создаю DLL со встроенным двоичным ресурсом. В настоящее время, когда я загружаю эту DLL, она отображает память в мое адресное пространство процесса. Проблема в том, что встроенный бинарный ресурс огромен, и я не хочу его оставлять, как только закончу его использовать.

Я попытался найти документацию по этому вопросу, и, очевидно, в файле PE есть разделы, которые не отображаются в памяти (раздел перемещения). Кроме того, я могу создать новые разделы и пометить его IMAGE_SCN_MEM_DISCARDABLE, но этот флаг игнорируется вне режима ядра.

Была функция API win, которая поддерживала освобождение ресурсов для 16-битной Windows, но не работала 32-битной. В документации сказано: "Эта функция устарела и поддерживается только для обратной совместимости с 16-разрядной Windows. Для 32-разрядных приложений Windows нет необходимости освобождать ресурсы, загруженные с помощью LoadResource. При использовании в 32- или 64-разрядных системах Windows., эта функция вернет FALSE". Я не знаю, что они подразумевают под этим, но кажется, что они не ожидают, что ресурсы будут огромными и могут быть размещены в адресном пространстве.

Можно ли как-нибудь отказаться от ресурсов, которые я загружаю после их использования?

1 ответ

Система откажется от них, если это необходимо. Пока вы не обращаетесь к памяти, она может быть удалена и выгружена, если системе нужна физическая память для чего-то другого. Таким образом, это не остановит использование физической памяти для того, кто в этом нуждается.

Тем не менее, связанные ресурсы не предназначены для огромных. Дело в том, что модуль отображается в непрерывный диапазон памяти. Если ваш модуль действительно огромен, то может быть невозможно найти такой непрерывный диапазон памяти. Более того, диапазон адресов модуля зарезервирован на весь срок службы ресурса. Это означает, что ничто другое в этом процессе не может использовать этот диапазон адресов виртуальной памяти. Таким образом, даже если можно найти непрерывный диапазон адресов, он навсегда зарезервирован для модуля, и этот диапазон адресов нельзя использовать ни для чего другого. И это может легко стать проблемой для 32-битных приложений.

Таким образом, помещая огромный ресурс в память, вы не будете подвергаться длительному истощению физических ресурсов, но наложите неизбежное ограничение на ресурсы адресного пространства виртуальной памяти.

Сделанный вывод заключается в том, что такие огромные объекты должны храниться во внешних файлах и не должны быть связаны с модулем как ресурсом. Если вам абсолютно необходимо использовать ресурс в модуле PE, поместите ресурс в отдельную DLL. Загрузите DLL с LoadLibraryвытащить ресурс используя дескриптор модуля LoadLibraryи затем выгрузите DLL с FreeLibrary,

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