Почему память не освобождается в top и pmap?

Я проверил код с помощью valgrind, утечки памяти нет.
но я использую «top», чтобы увидеть память, она стоит 295 МБ памяти после вызова «delete».
Я использую ‘pmap -x’, чтобы увидеть память, большая часть памяти на [anon]:

Address           Kbytes     RSS   Dirty Mode   Mapping
0000000001114000  301672  301588  301588 rw---    [ anon ]

Я не знаю, почему была освобождена память, но она все еще стоит 295 МБ. Кто-нибудь знает почему?

#include <map>
#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
void test8() {
map<string, map<string,string>* > m;
for (int i = 1; i < 10000; i++) {
map<string, string>* p = new map<string, string>();
for (int j = 1; j < 100; j++) {
(*p)[string(j,'a')] = string(j,'a');
}
m[string(i,'a')] = p;
}

map<string, map<string,string>* >::iterator it;
for (it = m.begin(); it != m.end(); it++) {
it->second->clear();
delete it->second;
}
m.clear();
cout << "free done" << endl;
}
int main(int argc, char**argv) {
test8();
getchar();
}

1

Решение

Кеширование, кеширование, кеширование. Ах да, и фрагментация.

Память распределяется через разные слои. Если ваше приложение выделяет память, оно запросит ее во время выполнения C / C ++. Среда выполнения C / C ++ проверит свои собственные структуры данных на наличие доступной памяти и, если она не будет, перенаправит вызов в ОС. В зависимости от среды выполнения C / C ++ (и версии) структуры данных среды выполнения C / C ++ могут быть обширными или среда выполнения C / C ++ может просто всегда перенаправлять вызов непосредственно в ОС. Для Microsoft Visual Studio (не использующей Linux в данный момент, извините) я знаю, что:

  • В старых версиях во время выполнения C / C ++ были довольно обширные структуры данных в памяти.
  • Новые версии, кажется, всегда перенаправляют вызов в ОС (Windows Heap)

Это означает, что при освобождении памяти среда выполнения C / C ++ может решить сохранить память (по нескольким причинам, включая возможность быстрее вернуть память, если вы решите снова выделить память), или может вернуть ее в ОС (если она уже есть). имеет много свободной памяти). Операционная система может делать то же самое: держать память готовой на случай, если вы захотите выделить ее снова, или пометить ее как освобожденную немедленно.

Ах да, фрагментация.
Память обычно делится на страницы. На Intel x86 и amd64 страница занимает 4 КБ. Каждая страница содержит некоторую информацию, в том числе:

  • права защиты (только чтение, чтение-запись, выполнение (см. DEP, бит NoX)
  • его фактическое место (физическая память, выгруженная в файл подкачки, …)

Предположим, ваше приложение выделяет 16 раз по 256 байт, и вам повезло, что вся эта память размещена на одной странице размером 4 КБ. Если вы теперь освободите 15 из этих распределений, 16-е выделение сохранит выделенную страницу памяти, не давая ОС пометить ее как освобожденную. Довольно легко написать приложение, которое выделяет 1,5 ГБ, а затем освобождает 1,4 ГБ и по-прежнему потребляет 1,5 ГБ памяти (в зависимости от ОС).

Это означает, что даже если вы освободили всю память, могут быть только некоторые внутренние структуры данных времени выполнения C / C ++ или некоторые сторонние структуры данных (возможно, некоторый кэш), которые могут сохранять некоторые страницы выделенными, хотя вы полностью освободили всю свою память.

0

Другие решения

Инструменты, которые вы используете, отслеживают объем памяти, выделяемой процессом из операционной системы, они не отслеживают размер выделения памяти, в настоящее время активного в вашей программе на C ++.

Когда вы распределяете память с помощью своего кода на C ++, возможно, вам придется выйти в ОС и попросить больше. Это увеличит значения, которые вы отслеживаете.

Тем не менее, когда вы освобождаете его, есть нет требований что это даст эту память назад в ОС, так как это может понадобиться снова очень скоро.

Итак, хотя ваша программа на C ++ освободила память, C ++ среда держит его на случай, если оно понадобится снова.

0

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

0
По вопросам рекламы [email protected]