Почему 32-разрядные процессы имеют ограничение в 2 ГБ ОЗУ?

3912
pfedotovsky

Мне любопытно, почему существует ограничение в 2 ГБ для 32-разрядного процесса в 32-разрядной ОС. Согласно сообщению в блоге Chat Question: Ограничения памяти для 32-разрядных и 64-разрядных процессов, ограничение может быть увеличено до 3 ГБ, но вопрос остается.

Я вижу, что физический лимит составляет 4 ГБ, так что 2 или 3 ГБ жестко запрограммированы в Windows? Почему бы не 4 ГБ, как 32-разрядный процесс может иметь на 64-разрядной ОС?

ПРИМЕЧАНИЕ. Этот вопрос был помечен как дубликат, но упомянутый вопрос относится к ограничению в 32 ГБ 32-разрядного адресного пространства. Это НЕ то, что я спрашиваю. Я специально спрашиваю, почему Windows ограничивает процессы до 2 ГБ - даже на 32-битной платформе. В принятом ответе упоминается об этом, но не объясняется почему.

5
«Почему бы не 4 Гб, как 32-битный процесс может иметь на 64-битной ОС?» - Microsoft решила об этом ограничении. «Я вижу, что физический лимит составляет 4 ГБ, поэтому 2 или 3 ГБ жестко запрограммированы в Windows?» - Да Ramhound 7 лет назад 0
32-битные окна отображают 2 ГБ памяти ядра для ускорения операций. поэтому только 2 ГБ доступны для процесса. Прочитайте книгу Windows Internals в следующий раз, там подробно объясняется magicandre1981 7 лет назад 0
Краткий ответ: Производительность. Предоставление каждому процессу 4 ГБ адресного пространства потребовало бы отдельного адресного пространства для использования системой. Переключение адресных пространств, переключение контекста, приводит к значительному снижению производительности. Многие приложения совершают частые вызовы ОС, для которых требуется доступ к системному адресному пространству, а системные прерывания также требуют этого. Ограничивая адресное пространство процесса до 2 ГБ, он может сосуществовать с системным адресным пространством 2 ГБ и избегать таких частых переключений контекста. Имейте в виду, что каждый процесс имеет свое собственное адресное пространство 2 ГБ, которое не используется совместно с другими. LMiller7 7 лет назад 0

2 ответа на вопрос

6
LMiller7

На платформе NT виртуальное адресное пространство 4 ГБ по умолчанию разделено на две части: нижние 2 ГБ для адресного пространства процесса и верхние 2 ГБ для использования системой.

Это адресное пространство является виртуальным и не зависит от объема оперативной памяти. Диспетчер памяти CPU и OS отображает части оперативной памяти в виртуальное адресное пространство по мере необходимости. Это очень сложно и не будет описано здесь. Это было дизайнерское решение, принятое в интересах производительности, безопасности и надежности.

Каждый процесс имеет свое собственное адресное пространство 2 ГБ, но есть только одно системное адресное пространство. Процессы изолированы в своем собственном частном адресном пространстве и не могут даже видеть других. При необходимости предусмотрена возможность обмена адресами между двумя или более процессами. Системное адресное пространство запрещено обычными процессами и доступно только компонентам уровня ядра, таким как сама ОС и драйверы устройств. Если процесс сбивается с пути, он может только навредить себе; другие процессы и ОС не затрагиваются.

Но почему бы не дать системе собственное частное адресное пространство, как для процессов? Это позволило бы выделить 4 ГБ адресного пространства для системы и каждого процесса. Это можно было сделать - но была проблема.

Предположим, что было сделано. Запущенный процесс будет иметь полный доступ к своему коду и данным, и все будет хорошо. Но что, если этот процесс делает вызов ОС, который требует доступа к системному адресному пространству, например, для операции ввода-вывода? Или что произойдет, если ядро ​​обработает прерывание?

Только адресное пространство запущенного процесса может быть замечено ЦП. Что делать? Решение состоит в том, чтобы сделать переключение контекста, которое отображает системное адресное пространство. ОС может сделать это довольно эффективно, но на это нужно время. Если бы к системному адресному пространству требовался частый доступ, накладные расходы на переключение контекста стали бы чрезмерными и производительность снизилась бы.

Должен быть лучший способ.

Было принято решение разделить общее адресное пространство 4 ГБ на две части по 2 ГБ каждая. Обработайте адресное пространство в нижних 2 ГБ и систему в верхних. Это позволяет системному адресному пространству всегда находиться в области видимости и быть доступным в любое время без переключения контекста. Как это часто бывает, дизайнерские решения принимаются по практическим соображениям.

Сейчас 2 ГБ могут показаться очень маленькими и ограниченными, но они были огромны, когда NT была выпущена в 1993 году. И не забывайте, что у каждого процесса есть свои 2 ГБ.

Я изо всех сил пытаюсь понять это. Похоже, вы говорите, что большая часть памяти ядра или, возможно, адреса отображаемых в памяти устройств ввода-вывода постоянно находятся в виртуальном адресном пространстве, т. Е. Даже во время работы пользовательского кода. Если это так, значит ли это, что пользовательский процесс может получить к нему доступ? Если это правда, это, очевидно, будет серьезным недостатком безопасности. Вы можете уточнить это? Scott 7 лет назад 0
Вся память ядра постоянно находится в адресном пространстве процесса объемом 4 ГБ, даже когда выполняется пользовательский код. Но только код уровня ядра имеет к нему доступ. Любая попытка доступа к памяти ядра процессом уровня пользователя завершится неудачей с исключением. Аппаратные устройства с отображением в памяти управляются по-разному (я не знаю деталей), но они также не доступны для пользовательского кода. Процесс уровня пользователя может видеть только свой собственный код и данные. Существует положение для совместного использования кода и данных между несколькими процессами. LMiller7 7 лет назад 1
3
blami

Согласно книге Windows Internals это было дизайнерское решение. Они разделяют все 4 ГБ виртуальной памяти на две части:

  • Виртуальное адресное пространство в режиме ядра 2 ГБ (окна памяти драйверов и т. Д.)
  • 2 ГБ виртуального адресного пространства в режиме пользователя (память для программ пользовательского пространства)

Тогда есть нерекомендованный /3GBпереключатель (который меняет пользователя ядра 1: 3 и может привести к неприятным ошибкам с драйверами, которые выделяются с абсолютным смещением), PAE и я полагаю, что был еще один API, который при использовании позволяет выделять невыгружаемую память и динамически привязывать его к адресному пространству программ (но мне жаль, что я не могу вспомнить его имя сейчас).

Проведите этот ответ через финишную черту, явно привязав его к процессам (как процесс относится к адресному пространству ядра и пользовательскому адресному пространству?). :-) fixer1234 7 лет назад 0