Миф: Опция /3GB увеличивает адресное пространство в режиме пользователя для всех программ.


Перевод с блога The Old New Thing. Оригинал здесь.

Нет, это происходит только для программ, помеченных атрибутом /LARGEADDRESSAWARE.

В целях совместимости, только программы, которые явно обозначили, что они готовы к работе в адресном пространстве, большем чем 2Гб, получают увеличенное виртуальное адресное пространство. Остальные программы работают в обычном 2-х гигабайтном виртуальном адресном пространстве и адресное пространство между 2Гб и 3Гб остается неиспользованным.

Почему?

Потому что слишком большое количество программ предполагает, что старший бит адресов в адресном пространстве пользователя всегда равен 0, причем, зачастую непреднамеренно. В MSDN есть статья, где перечислены случаи, когда программы работают, предполагая это. Например, программа становится зависимой от значения старшего бита адреса, когда вычисляется середина между двумя указателями при помощи формулы (a+b)/2. Это может привести к переполнению а, значит, к неверным результатам. Значит, нельзя просто взять готовую программу, которую написали не вы, пометить ее атрибутом /LARGEADDRESSAWARE, и объявить свою работу выполненной. Вы должны убедиться, что авторы этой программы проверили свой код, и он не содержит никаких предположений насчет 2Гб. (А тот факт, что авторы не пометили свою программу совместимой с 3Гб адресным пространством, свидетельствует о том, что такой проверки произведено не было. Если бы такая проверка была, они бы пометили программу атрибутом /LARGEADDRESSAWARE!)

Пометка программы атрибутом /LARGEADDRESSAWARE говорит операционной системе "Вперед, предоставь этой программе доступ к дополнительному гигабайту пользовательского адресного пространства", и в результате, адреса из третьего гигабайта становятся допустимыми значениями, возвращаемыми функциями выделения памяти. Если вы установите в менеджере памяти флаг "Сверху вниз", это говорит ему о том, что необходимо вначале выделять память по старшим адресам, тем самым вынуждая программу работать с такими адресами раньше, чем это могло произойти. Это очень удобно при тестировании программы в режиме с включенной опцией /3GB, так как проблемные адреса будут использованы раньше, чем обычно.

Домашнее задание: Найдите ошибку в следующей функции.

#define BUFFER_SIZE 32768

BOOL  IsPointerInsideBuffer(const BYTE *p, const BYTE *buffer)

{

  return p >= buffer && p — buffer < BUFFER_SIZE;

}

Реклама
Запись опубликована в рубрике память. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s