Мое приложение нуждается в большом количестве памяти и большой структуре данных для выполнения своей работы.
Зачастую приложению требуется более 1 ГБ памяти, а в некоторых случаях моим клиентам действительно необходимо использовать 64-разрядную версию приложения, поскольку они имеют несколько гигабайт памяти.
В прошлом я мог легко объяснить пользователю, что, если объем используемой памяти достигает 1,6–1,7 ГБ, это означает «нехватка памяти» или она действительно близка к ситуации «нехватка памяти», и что ему необходимо уменьшить их память или перейти на 64-битную версию.
В прошлом году я заметил, что часто приложение использует только около 1 ГБ, прежде чем оно уже исчерпывает память. После некоторых исследований выяснилось, что причиной этой проблемы является фрагментация памяти. Я использовал VMMAP (утилиту SysInternals), чтобы посмотреть на использование памяти моим приложением, и увидел что-то вроде этого:
![Address Space Fragmentation](https://i.stack.imgur.com/zYML2.png)
Оранжевые области - это память, выделенная моим приложением. Фиолетовые области - это исполняемый код.
Как вы можете видеть в нижней половине изображения, фиолетовые области (которые являются DLL) загружаются по разным адресам, что приводит к фрагментации моей памяти. На самом деле это не проблема, если у моего клиента нет большого количества данных, но если у моего клиента есть наборы данных, которые занимают более 1 ГБ, а часть приложения нуждается в большом блоке памяти (например, 50 МБ), это может привести к ошибке выделения памяти, что приведет к сбою приложения.
Большинство моих структур данных основаны на STL и часто не требуют больших кусков непрерывной памяти, но в некоторых случаях (например, очень большие строки) действительно необходимо иметь непрерывный блок памяти. К сожалению, не всегда возможно изменить код, чтобы он не нуждался в таком непрерывном блоке памяти.
Вопросы:
- Как я могу влиять на место, где DLL загружаются в память, без явного использования REBASE для всех DLL на компьютере клиента или без явной загрузки всех DLL.
- Есть ли способ указать адреса загрузки DLL в вашем файле манифеста приложения?
- Или есть способ указать Windows (через файл манифеста?) Не разбрасывать библиотеки DLL вокруг (я думаю, что это рассеяние называется ASLR).
Конечно, лучшее решение - это то, на которое я могу влиять из файла манифеста моего приложения, поскольку я полагаюсь на автоматическую / динамическую загрузку DLL-файлов Windows.
Мое приложение является приложением смешанного режима (управляемое + неуправляемое), хотя основная часть приложения неуправляемая.
Есть предложения?