• Авторизация


Windows и объём памяти. 26-04-2009 19:28 к комментариям - к полной версии - понравилось!


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
 

Теория:

  1. Ограничения Windows.
    Полный список ограничений по памяти можно посмотреть на страничке Memory Limits for Windows Releases.
    Нас же интересуют только ограничения виртуальной памяти:

    Memory and Address Space Limits
    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

    Виртуальная память - В Windows реализована система виртуальной памяти, основанная на плоском (линейном) адресном пространстве. Она создаёт каждому процессу иллюзию того, что у него есть собственное большое и закрытое адресное пространство [1, c.15].

    В 32-bit Windows:
    Объём виртуального адресного пространства 4ГБ, распределено:
    2ГБ - user mode (пользовательский режим), 2ГБ - kernel mode (режим ядра).
    Т.е. приложению (процессу) доступно примерно 2ГБ виртуального адресного пространства в независимости от количества установленной физической памяти. Размер виртуальной памяти в режиме пользователя можно увеличить до 3ГБ используя специальные параметры (ключи) загрузки /3GB /userva=xxxx (xxxx в МБ в диапазоне 2048 - 3072) в файле Boot.ini (Параметры, используемые в файле Boot.ini), рекомендуемый максимум значений userva 2900–3030, более детально можно узнать в статье Использование параметра /userva с параметром /3GB для настройки объема виртуальной памяти в режиме пользователя в пределах между 2 и 3 ГБ. Чтобы приложение смогло использовать виртуальную память больше 2ГБ оно должно быть скомпилировано с параметром IMAGE_FILE_LARGE_ADDRESS_AWARE.

    Виртуальное адресное пространство
    (по-умолчанию)
    Виртуальное адресное пространство
    с параметром загрузки /3GB
    /userva=3072

    Младшие 2ГБ (0x00000000 - 0x7FFFFFFF)
    Старшие 2ГБ (0x80000000 - 0xFFFFFFFF)

    Младшие 3ГБ (0x00000000 - 0xBFFFFFFF)
    Старшие 1ГБ (0xC0000000 - 0xFFFFFFFF)



    В 64-bit Windows для 32-bit процесса доступно:
    2ГБ и 4ГБ (если приложение компилируется с параметром IMAGE_FILE_LARGE_ADDRESS_AWARE).

  2. У каждого приложения (dll-ки и т.п.) есть стартовый адрес (Image Base Address), с которого она должна начать загрузку. При загрузке приложения в его адресное пространство подгружаются разные dll-ки, которые использует приложение, а также dll-ки от других программ (Outpost Firewall, FileBox eXtender, Prio - Process Priority Saver, ABBYY Lingvo, и т.п.). Соответственно в адресном пространстве появляются барьеры. При одинаковых Image Base Address у dll-ки (и т.п.) система загружает dll-ку с другого адреса (обычно с младших адресов).

  3. Большинство программ выделяют память непрерывными блоками, и если не удаётся выделить, то программы или выдают сообщение: Недостаточно памяти; или вываливаются с ошибкой: Ошибка произошла т.к. недостаточно памяти; или вываливаются с ошибкой, которая мало о чём говорит.

 

Практика:

В примерах использовались ОС 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

Process Explorer -  View - Select Columns

Для примера возьмём процесс 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]




Литература:

  1. М. Руссинович, Д. Соломон. Внутреннее устройство Microsoft Windows: Windows Server 2003, Windows XP и Windows 2000., — 4-е изд. СПб.: Питер, 2005.


 

Specially for forum.ru-board.com

 

  (c)   forall.ru-board.com/egor23/online/FAQ/Virtual_Memory/Limits_Virtual_Memory.html

вверх^ к полной версии понравилось! в evernote


Вы сейчас не можете прокомментировать это сообщение.

Дневник Windows и объём памяти. | DemonSDA - Записки сетевого серфера. | Лента друзей DemonSDA / Полная версия Добавить в друзья Страницы: раньше»