new[] не уменьшает доступную память до заполнения

Это в C++ на CentOS 64bit с использованием G++ 4.1.2.

Мы пишем тестовое приложение для загрузки памяти в системе n гигабайт. Идея состоит в том, что общая нагрузка на систему контролируется через SNMP и т. Д. Так что это всего лишь способ осуществления мониторинга.

Однако мы увидели, что просто делаем:

char* p = new char[1000000000];

не влияет на используемую память, как показано в верхней или свободной -m

Распределение памяти кажется "реальным" только после того, как память записана в:

memcpy(p, 'a', 1000000000);   //shows an increase in mem usage of 1GB

Но мы должны записать всю память, просто запись в первый элемент не показывает увеличение используемой памяти:

p[0] = 'a';    //does not show an increase of 1GB.

Это нормально, полностью ли выделена память? Я не уверен, что инструменты, которые мы используем (top и free -m), отображают неверные значения или что-то умное происходит в компиляторе или во время выполнения и / или в ядре.

Такое поведение наблюдается даже в отладочной сборке с отключенными оптимизациями.

Насколько я понимаю, новый [] сразу же выделил память. Задерживает ли среда выполнения C++ это фактическое распределение до тех пор, пока к нему не будет получен доступ. В таком случае может ли исключение из-за нехватки памяти быть отложено до тех пор, пока не произойдет фактическое выделение памяти, пока не будет осуществлен доступ к памяти?

Так как это не проблема для нас, но было бы неплохо узнать, почему это происходит именно так!

Ура!

Редактировать:

Я не хочу знать о том, как мы должны использовать Векторы, это не OO / C++ / текущий способ работы и т. Д. И т. Д. Я просто хочу знать, почему это происходит, а не предлагать для альтернативных способов попробовать это.

3 ответа

Решение

Пожалуйста, найдите для overcommit. Linux по умолчанию не резервирует память до тех пор, пока к ней не будет получен доступ. И если в итоге вам потребуется больше памяти, чем доступно, вы не получите ошибку, но случайный процесс будет убит. Вы можете контролировать это поведение с /proc/sys/vm/*,

IMO, overcommit должен быть индивидуальным, а не глобальным. И по умолчанию не должно быть чрезмерного.

Когда ваша библиотека выделяет память из ОС, ОС просто зарезервирует диапазон адресов в виртуальном адресном пространстве процесса. У ОС нет причин фактически предоставлять эту память, пока вы ее не используете - как вы продемонстрировали.

Если вы посмотрите на, например, /proc/self/maps вы увидите диапазон адресов. Если вы посмотрите на использование памяти сверху, вы не увидите его - вы еще не используете его.

О второй половине вашего вопроса:

Стандарт языка не допускает каких-либо задержек при создании bad_alloc. Это должно произойти как альтернатива new[], возвращающему указатель. Это не может произойти позже!

Некоторые операционные системы могут пытаться перераспределить память и потерпеть неудачу позже. Это не соответствует стандарту языка C++.

Другие вопросы по тегам