странная память ведет себя из изменения размера и резерва о векторе - PullRequest
1 голос
/ 18 апреля 2019

Я знаю, что резерв (n) выделяет только n пробелов, но размер равен 0.

, в то время как resize (n) выделяет n пробелов, а размер - n.

, но когда я наблюдаю изменение памятиоконным диспетчером задач в тесте, я смущен результатом.

У меня уже есть код, занимающий 100 МБ, затем я тестирую код, приведенный ниже, шаг за шагом:

vector<Eigen::Vector4f> vec;
vec.resize(5000000); //memory still take 100MB???
vec.push_back(Eigen::Vector4f::Zero()); //memory take 181MB???

Мне любопытно, почему изменение размера не изменило память, пока не будет push_back

vector<Eigen::Vector4f> vec;
vec.reserve(5000000); //memory still take 100MB???
for(int i = 0 ; i < 5000000; i++){
    vec.push_back(Eigen::Vector4f::Zero()); // memory increase one by one from 100MB to 181MB
}

резерв также не выделил память?почему?

1 Ответ

7 голосов
/ 18 апреля 2019

Это не вызвано использованием reserve() или resize(). Это вызвано тем, что операционная система вашего хоста выполняет ленивое распределение.

Первым шагом является то, что operator new() (используется распределителем по умолчанию vector) запрашивает много памяти у ОС. ОС указывает вашей программе, что она выполнила выделение (например, вернув действительный дескриптор для памяти в operator new(), который, в свою очередь, возвращает действительный указатель на вашу программу), но на самом деле НЕ выделяет память.

Впоследствии, когда ваша программа делает что-то, что зависит от выделяемой памяти, ОС ловит неизбежный сигнал от аппаратного блока управления памятью (например, как сбой страницы) и затем выделяет страницу. Это происходит при использовании вами vector s push_back().

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

Одним из следствий этого является то, что выделение может - насколько это касается вашей программы - успешно, но более позднее использование этой выделенной памяти может завершиться неудачно (например, вызов push_back() после использования reserve() может завершиться неудачей).

...