Limits of Virtual Memory in Windows - Ограничения виртуальной памяти в Windows
Автор: egor23, 29.05.2008 14:34, последнее обновление 07.04.2009 08:05
обсуждение обзора на форуме
Предисловие
Данный обзор рассказывает об ограничениях виртуальной памяти (Virtual Memory) в 32-bit Windows, и в 64-bit Windows для 32-bit приложений. А также раскрывает причины появлений сообщений -
Недостаточно памяти
, если раньше при появлении неинформативного сообщения -
"Недостаточно памяти"
, это списывалось на то, что установлено мало оперативной памяти, то теперь списывать на это не получается (установлено часто 2ГБ и более оперативной памяти), и возникает вопрос: Почему не хватает памяти?
В
есть статьи:
Преодолевая ограничения Windows: физическая память
Преодолевая ограничения Windows: виртуальная память
В данном обзоре не рассматриваются ограничения Windows по физической памяти, о них можно прочитать в следующих статьях:
Четыре гигабайта памяти - недостижимая цель?
Поддержка памяти большого размера в Windows Server 2003 и Windows 2000
Physical Address Extension (PAE) [1, c.458]
Operating Systems and PAE Support
Теория:
| Memory type | Limit in 32-bit Windows | Limit in 64-bit Windows |
| Общее виртуальное адресное пространство | 4 ГБ | 16 ТБ |
| Виртуальное адресное пространство для одного 32-разрядного процесса | 2 ГБ до 3 ГБ, если приложение компилируется с параметром IMAGE_FILE_LARGE_ADDRESS_AWARE и система загружается с ключом /3GB |
2 ГБ 4 ГБ, если приложение компилируется с параметром IMAGE_FILE_LARGE_ADDRESS_AWARE |
| Виртуальное адресное пространство для одного 64-разрядного процесса | — | 2 ГБ x64: 8 ТБ, если приложение компилируется с параметром IMAGE_FILE_LARGE_ADDRESS_AWARE Intel IPF: 7 ТБ, если приложение компилируется с параметром IMAGE_FILE_LARGE_ADDRESS_AWARE |
|
Виртуальное адресное пространство
(по-умолчанию) |
Виртуальное адресное пространство
с параметром загрузки /3GB /userva=3072 |
|
|
Практика:
В примерах использовались ОС Windows:
Windows XP Professional SP2
Windows XP Professional x64 Edition SP2
Есть приложения у которых нет проблем из-за нехватки виртуальной памяти: Adobe Photoshop, GIMP и т.п.
Из п.1 теории видно, что памяти даётся 32-bit приложению много 2ГБ (по-умолчанию), но в п.2 и п.3 описываются "подводные камни", на которых спотыкаются ряд приложений, далее пойдёт речь о таких приложениях и каким образом можно обходить эти "подводные камни".
Если приложение выделяет память небольшими кусочками, то оно займёт всю доступную виртуальную память и уже после выдаст сообщение или вывалиться с ошибкой, так происходит с 3D-Game (S.T.A.L.K.E.R.: Shadow of Chernobyl и т.п.) и т.д.
Если приложение выделяет память большими блоками, то оно практически сразу выдаст сообщение:
недостаточно памяти для выполнения операции...:
7-zip, WinRK и т.п. - при создании\распаковки архива;
Paint.NET и т.п. - при создании\открытии изображения;
и т.п. список приложений в которых возникают такие проблемы большой.
Связано это с тем, что первые 2ГБ виртуальной памяти фрагментированы, разбиты на непрерывные блоки, и при попытке выделить блок памяти больший имеющегося приложение говорит, что недостаточно памяти.
Чтобы увидеть, как фрагментировано адресное пространство конкретного процесса, в данный момент времени, воспользуемся утилитой VMMap, офф.сайт. Для примера возьмём процесс 7zG.exe (7-Zip GUI), выберем Type Free (свободные области памяти), отсортируем столбец Size по убыванию:
[244x166]
Максимальный свободный блок виртуальной памяти - 1201.6МБ (1230488кБ).
В Options отметим Show Free Regions (отображать свободные области памяти), выберем Type Total (все области памяти), отсортируем столбец Address по возрастанию, в итоге видим, как поделено адресное пространство виртуальной памяти:
[244x166]
Для оценки фрагментации адресного пространства процесса "вручную",
возьмём Process Explorer (с июля 2006 г. принадлежит корпорации Microsoft), офф.сайт.
Process Explorer сможет нам показать какие dll-ки подцепились к процессу, и с каких адресов это было сделано. Тем самым мы сможем узнать как примерно фрагментировано адресное пространство процесса в первых 2ГБ, т.к. в данном случае не учитываем размер памяти занимаемый dll-кой, а также делаем допущение, что между dll-ками нет зарезервированных регионов адресного пространства.
Для начала в настройках Вида (View - Select Columns...), вкладка DLL, включим отображение столбцов:
Image Base Address - столбец Image Base
Base Address - столбец Base
Mapped Size - столбец Size

Для примера возьмём процесс 7zG.exe (7-Zip GUI), смотрим столбец Base (Base Address) и например в уме считаем какой непрерывный блок самый большой:
[257x166]
Обвёл основные контрольные точки (остальные нас не интересуют, в данном случае, т.к. блоки будут ещё меньше).
Примечание: Промежуточные значения в МБ приведены для справки. Результат в МБ округляем до меньшего целого.
0x10000000 (256МБ)
0x5B260000 (1458МБ)
0x746E0000 (1862МБ)
0x5B260000 - 0x10000000 = 0x4B260000 (1202МБ)
0x746E0000 - 0x5B260000 = 0x19480000 (404МБ)
Максимальный размер непрерывного блока 1202МБ.
Ниже на картинке изображено, как это выглядит:
[542x117]
Для оценки непрерывных блоков в виртуальной памяти можно воспользоваться memo.exe. Приложение консольное, что имеет свои плюсы - к консольным приложениям подцепляются меньше dll-ок.
memo.exe - выводит непрерывные блоки размером от 1МБ и более, округляя до меньшего целого.
В комплекте идут memo4g.exe\memo2g.exe - отличие memo4g.exe от memo2g.exe выставлен флаг /LARGEADDRESSAWARE, что даёт программе доступ к виртуальным адресам старше 2ГБ, можно наглядно увидеть, что будет иметь программа с выставленным флагом /LARGEADDRESSAWARE и что не будет, если флаг не выставлен.
Подчёркиваю: memo.exe выводит свои непрерывные блоки относительно среды Windows.
В 32-bit Windows:
memo2g.exe
Allocated 1911 mb, addr=00480000
Непрерывный блок размером 1911МБ с начальным адресом 0x480000.
[668x295]
memo4g.exe
/3GB /USERVA=3072
Получили дополнительный блок:
Allocated 1023 mb, addr=7FFF0000
Непрерывный блок размером 1023МБ с начальным адресом 0x7FFF0000
[668x307]
В 64-bit Windows:
memo2g.exe
[668x319]
memo4g.exe
[668x319]
В итоге - при использовании параметра IMAGE_FILE_LARGE_ADDRESS_AWARE 32-bit приложение получит дополнительно непрерывный блок:
в 32bit Windows - до 1023МБ;
в 64bit Windows - 2047МБ,
причём данные блоки будут доступны 32-bit приложению (не только консольному) всегда.
В топике FreeArc были и другие логи memo4g.exe\memo2g.exe.
Если программист забыл или не помнил про флаг IMAGE_FILE_LARGE_ADDRESS_AWARE ничего это дело поправимое. Информация находится в заголовке исполняемого файла (PE).
Portable Executable (PE) - Портируемый формат исполняемых файлов.
Portable Executable - Wikipedia, the free encyclopedia
Portable Executable — Википедия
Спецификация PE - Microsoft Portable Executable and Common Object File Format Specification
Для начала надо определится стоит флаг или нет. Для это можно воспользоваться приложениями выводящими информация о PE (PE Viewer) или использовать редактор PE (PE editor).
Для просмотра можно воспользоваться следующими приложениями:
ExeInfo
[629x348]
Program to analyze PE files
[927x469]
Если флаг не выставлен, то его можно выставить хоть вручную - в нужном месте, нужный байтик поправить.
Для изменения флага (выставить\убрать) есть EDITBIN.EXE идёт с Microsoft Visual Studio:
Выставляем флаг: EDITBIN.EXE /LARGEADDRESSAWARE proga.exe
Убираем флаг: EDITBIN.EXE /LARGEADDRESSAWARE:NO proga.exe
Microsoft Visual Studio
Microsoft Visual C++ 2005 Express Edition
Microsoft Visual Studio 2008 Express Edition
Windows SDK for Windows Server 2008 and .NET Framework 3.5
EDITBIN.EXE есть также в MASM32
Только выставить флаг можно с помощью 4GB Patch:
[290x186]
Для просмотра и изменения можно воспользоваться CFF Explorer, также позволяет менять и другие параметры:
[765x570]
Литература:
Specially for forum.ru-board.com
(c) forall.ru-board.com/egor23/online/FAQ/Virtual_Memory/Limits_Virtual_Memory.html