2010-07-03 1 views
1

У меня есть std :: vector класса OGLSHAPE.Это обычное поведение для std :: vector?

Каждая форма имеет вектор структуры SHAPECONTOUR, который имеет вектор с плавающей точкой и вектор вектора double. он также имеет вектор структуры структуры, в которой есть вектор float.

Первоначально моя программа запускается с использованием 8,7 МБ оперативной памяти. Я заметил, что когда я начал заполнять эти данные, добавив удвоение и поплавки, память быстро поднялась, а затем выровнялась. Когда я очищаю вектор OGLSHAPE, используется еще около 19 МБ. Затем, если я нажму около 150 фигур, то очистите их, теперь я использую около 19.3 МБ бара. Я бы подумал, что это логично, если в первый раз это изменилось с 8,7 до 19, что в следующий раз это будет примерно до 30. Я не уверен, что это такое. Я думал, что это утечка памяти, но теперь я не уверен. Все, что я делаю, это push-числа в std :: векторы, ничего больше. Поэтому я ожидаю вернуть всю свою память. Что может быть причиной этого?

Благодаря

* редактировать, хорошо его фрагментации памяти от распределения много мелких вещей, как это может быть решена?

+3

На какой платформе вы работаете и как вы измеряете использование памяти? –

+0

«Что может быть причиной этого?» Утечка памяти в OGLSHAPE может легко это сделать. – SigTerm

+0

Вы можете опубликовать упрощенную версию своего кода? – nas

ответ

8

Вызов станд :: вектор <> :: ясно() не обязательно все бесплатно выделенной памяти (это зависит от реализации станд :: вектор <>). Это часто делается с целью оптимизации, чтобы избежать ненужных распределений памяти.

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

template <typename T> 
inline void really_free_all_memory(std::vector<T>& to_clear) 
{ 
    std::vector<T> v; 
    v.swap(to_clear); 
} 

// ... 
std::vector<foo> objs; 

// ... 
// really free instance 'objs' 
really_free_all_memory(objs); 

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

+0

Я делаю, как вы только что упомянули для вектора OGLSHAPE, и я предполагаю, что все остальные векторы называют их деструктором – jmasterx

+0

@hkaiser, хороший совет. Интересно, почему бы не добавить это как стандартную функциональность в STL (что-то вроде: std :: vector :: free_all_memory). – Patrick

+1

@Patrick: Я думаю, потому что он легко может быть выражен как однострочный: 'std :: vector () .swap (v);' Не стоит добавлять в стандартную библиотеку, когда это такая распространенная идиома при этом точка. –

0

Используйте правильные инструменты для наблюдения за использованием вашей памяти, например. (в Windows) используйте Process Explorer и наблюдайте за частными байтами. Не смотрите на виртуальное адресное пространство, так как это показывает самый высокий адрес памяти. Фрагментация является причиной большой разницы между обоими значениями.

понимает также, что есть много слоев между приложением и операционной системой:

  • БПППОМ :: вектор не обязательно бесплатно вся памятью немедленно (см кончика hkaiser)
  • в C Run Time не всегда возвращает всю память в операционную систему
  • Операции с кучей операционной системы могут не освобождать всю память, поскольку она может освобождать только полные страницы (4 КБ). Если используется 1 байт страницы 4 КБ, страница не может быть освобождена.
0

В игре есть несколько возможных вещей.

Во-первых, то, как память работает в наиболее распространенных библиотеках времени выполнения C и C++, является то, что когда она назначается приложению из операционной системы, она редко возвращается в ОС. Когда вы освобождаете его в своей программе, диспетчер памяти new держит его на месте, если вы снова попросите больше памяти. Если вы это сделаете, он вернет вас для повторного использования.

Другая причина в том, что сами векторы обычно не уменьшают их размер, даже если вы очистите их.Они сохраняют «потенциал», который у них был на самом высоком уровне, так что он быстрее заполняет их. Но если вектор когда-либо будет уничтожен, эта память вернется к библиотеке времени выполнения, которая будет выделена снова.

Итак, если вы не уничтожаете свои векторы, они могут хранить память внутри вас. Если вы используете что-то в операционной системе для просмотра использования памяти, возможно, он не знает, сколько «свободной» памяти ожидает в используемых библиотеках времени выполнения, а не возвращается в операционную систему.

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

+0

Как я могу решить проблему фрагментации памяти? – jmasterx

+0

Это то же самое, что утечка памяти? – jmasterx

+0

Вам вообще не нужно беспокоиться о фрагментации памяти. Это естественно и редко становится серьезной проблемой. Ничего из того, что я изложил, это утечка памяти, просто препятствия для вас обнаружить, существует ли утечка памяти, не делая что-то более сложное. Используйте отладчик, который отслеживает память, и он скажет вам, есть ли у вас утечка. – SoapBox

Смежные вопросы