вслепую применяя флаг LargeAddressAware
к своему 32-битному исполняемому файлу, развертывает бомбу замедленного действия !
установив этот флаг вы свидетельствуете об ОС:
да, мое приложение (и все библиотеки DLL, загружаемые во время выполнения) может обрабатывать адреса памяти до 4 ГБ.
поэтому не ограничивайте VAS для процесса до 2 ГБ, но разблокируйте полный диапазон (4 ГБ) ".
но можете ли вы действительно гарантировать?
Вы берете на себя ответственность за все системные DLL, распространяемые Microsoft и сторонние модули, которые ваш процесс может использовать?
обычно, выделение памяти возвращает виртуальные адреса в порядке от низкого до высокого. поэтому, если ваш процесс не потребляет много памяти (или имеет очень фрагментированное виртуальное адресное пространство), он никогда не будет использовать адреса за пределами 2 ГБ. это скрывает ошибки, связанные с высокими адресами.
если такие ошибки существуют, их трудно идентифицировать. они будут время от времени появляться «рано или поздно». это просто вопрос времени.
К счастью, в ОС Windows встроен чрезвычайно удобный системный коммутатор:
для целей тестирования используйте параметр реестра MEM_TOP_DOWN.
это заставляет все выделения памяти идти сверху вниз вместо обычного снизу вверх.
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management]
"AllocationPreference"=dword:00100000
(это шестнадцатеричный 0x100000. Конечно, требуется перезагрузка Windows)
с включенным этим переключателем вы будете выявлять проблемы «скорее», чем «позже».
в идеале вы увидите их «с самого начала».
примечание: для первого анализа я настоятельно рекомендую инструмент VMmap
( SysInternals ).
выводы:
при применении флага LAA к 32-битному исполняемому файлу обязательно полностью протестировать его на ОС x64 с установленным переключателем TopDown AllocationPreference
.
для проблем в ваш собственный код вы можете их исправить.
просто чтобы назвать один очень очевидный пример: используйте целые числа без знака вместо целых чисел со знаком для указателей памяти.
при возникновении проблем с сторонними модулями, вы должны попросить автора исправить его ошибки. если это не сделано, лучше удалите флажок LargeAddressAware из вашего исполняемого файла.
примечание о тестировании:
Переключатель реестра MemTopDown не достигает желаемых результатов для модульных тестов , которые выполняются "бегущим тестом", для которого не LAA включен.
см .: Модульное тестирование для x86 LargeAddressAware совместимость
PS:
также очень «родственным» и довольно интересным является переход с 32-битного кода на 64-битный.
примеры см .: