Как получить объем виртуальной памяти, доступной в C ++?

StackOverflow https://stackoverflow.com/questions/4215127

Вопрос

Я хотел бы отобразить файл в память, используя функцию MMAP и хотел бы знать, достаточно ли количество виртуальной памяти на текущей платформе для отображения огромного файла. Для 32 системы я не могу отобразить файл больше 4 ГБ.
Было бы std::numeric_limits<size_t>::max() Дайте мне размер адресуемой памяти или есть ли другой тип, который я должен тестировать (OFF_T или что-то еще)?

Как лежат Райан указывает на его комментарий, «виртуальная память» здесь не используется. Однако возникает вопрос: имеется тип, связанный с указателем, и он имеет максимальное значение, которое определяет верхний предел того, что вы можете, возможно, артируют вашу систему. Что такое тип? Это size_t или, возможно, ptrdiff_t?

Это было полезно?

Решение

size_t Требуется только достаточно большой для хранения самых больших возможных непрерывных объектов. Это мая Не быть таким же, как размер адресного пространства (на системах с сегментированной моделью памяти, например)

Однако на общих платформах с плоским пространством памяти, два равны, и поэтому вы можете уйти с использованием size_t На практике, если вы знаете целевой ЦП.

Во всяком случае, это на самом деле не говорит вам ничего полезного. Конечно, 32-битный CPU имеет пространство памяти 4 ГБ, и поэтому size_t это 32-битное целое число без знака. Но это ничего не говорит о том, сколько вы можете выделить. В некоторой части пространства памяти используется ОС. И некоторые части уже используются вашим собственным приложением: для отображения исполняемого файла в память (а также любые динамические библиотеки, которые он может использовать), для стека каждого потока, выделенная память на куче и так далее.

Так что нет, хитрости, такие как размером size_t Рассказывает вам немного о адресном пространстве, в котором вы работаете, но ничего особенного. Вы можете спросить ОС, сколько памяти используется вашим процессом и другими метриками, но опять же, это на самом деле не помогает вам много. Процесс можно использовать лишь пару мегабайт, но имею ли, что распространилось на столько небольших ассигнований, что невозможно найти смежный блок памяти больше 100 МБ, скажем,. И вот, на 32-битной машине, с процессом, который почти не использует память, вы бы вряд ли сделаете такое распределение. (И даже если ОС имел волшебный WhatIsTheLargestPossibleMemoryAllocationICanMake() API, что еще не поможет вам. Это скажет вам, что вам нужно от минуты назад. Отказ У вас нет никакой гарантии, что ответ все равно будет действителен к тому времени, когда вы пытались сопоставить файл.

Так действительно, лучшее, что вы можете сделать, это пытаться Чтобы сопоставить файл и посмотреть, не удается ли это.

Другие советы

Привет, вы можете использовать GlobalMemoryStatusex и VirtualQueryex, если вы кодируете в Win32

Дело в том, что размер указателя вам ничего не говорит о том, сколько из этого «адресное пространство» на самом деле доступно для вас, т. Е. Можно сопоставить как единый непрерывный кусок.

Это ограничено:

  • операционная система. Он может выбрать только подмножество теоретически возможного диапазона адресов, доступных вам, поскольку память для смещения необходима для OS-собственных целей (например, скажем, создавая графическую карту Framebuffer видимым, и, конечно, для использования самой ОС. ).
  • Настраиваемые пределы. На Linux / Unix команда «ULIMIT» соответствует. Setrlimit () Системный вызов позволяет ограничить максимальный размер адресного пространства приложения различными способами, а Windows имеет аналогичные параметры с помощью параметров реестра.
  • История приложения. Если приложение широко использует отображение памяти, адресное пространство может фрагмент ограничение максимального размера «доступных» смежных виртуальных адресов.
  • аппаратная платформа. Некоторые процессоры имеют адресные пространства с «отверстиями»; an example of that is 64bit x86 where pointers are only valid if they're between 0x0..0x7fffffffffff or 0xffff000000000000 and 0xffffffffffffffff. Т.е. у вас 2x128tb вместо полного 16Eb. Подумайте об этом как 48-битные «подписанные» указатели ...

Наконец, не путайте «доступное память» и «доступное адресное пространство». Существует разница между выполнением malloc (kemybigsize) и MMAP (..., keybigsize, ...), потому что первое может потребовать наличия физической памяти для размещения запроса, в то время как последний обычно требует только доступности большого Диапазон адресов.

Для платформ Unix часть ответа является использование GetrLimit (Rlimit_as), поскольку это дает верхнюю границу для текущего вызова вашего приложения - как сказал, пользователь и / или admin могут настроить это. Вы гарантированы, что любая попытка MMAP районов больше, чем потерпит неудачу.

Ваш рефрасированный вопрос «Верхний предел того, что вы можете, возможно, адрес в вашей системе», несколько вводят в заблуждение; Это специфическая архитектура оборудования. Существует 64-битная архитектура (X64, SPARC), чья MMU happy позволяет (uintptr_t) (- 1) как действительный адрес, то есть вы можете что-то набрать на последнюю страницу 64-битного адресного пространства. Позволяет ли операционную систему возможность сделать это или нет, снова является совершенно другим вопросом ...

Для пользовательских приложений «Высокая отметка» не (всегда) фиксирована априори. Это настраивается на EG Solaris или Linux. Вот где приходит Getrlimit (Rlimit_as).

Обратите внимание, что снова, по спецификации, нечего предотвращать нечего предотвращения (странной) дизайна операционной системы, например, вкладывающих стеки приложений и кучи в адресах «Низкие» при наличии кода на «высоких» адресах, на платформе с адресной космическими отверстиями. Отказ Вам понадобится полные 64-битные указатели там, не могут сделать их меньшими, но может быть произвольным числом «недоступных / недействительных» диапазонов, которые никогда не доступен для вашего приложения.

Можешь попробовать sizeof(int*). Отказ Это даст вам длину (в байтах) указателя на целевой платформе. Таким образом, вы можете узнать, насколько велико адресное пространство.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top