Я проверил код с помощью 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();
}
Кеширование, кеширование, кеширование. Ах да, и фрагментация.
Память распределяется через разные слои. Если ваше приложение выделяет память, оно запросит ее во время выполнения C / C ++. Среда выполнения C / C ++ проверит свои собственные структуры данных на наличие доступной памяти и, если она не будет, перенаправит вызов в ОС. В зависимости от среды выполнения C / C ++ (и версии) структуры данных среды выполнения C / C ++ могут быть обширными или среда выполнения C / C ++ может просто всегда перенаправлять вызов непосредственно в ОС. Для Microsoft Visual Studio (не использующей Linux в данный момент, извините) я знаю, что:
Это означает, что при освобождении памяти среда выполнения C / C ++ может решить сохранить память (по нескольким причинам, включая возможность быстрее вернуть память, если вы решите снова выделить память), или может вернуть ее в ОС (если она уже есть). имеет много свободной памяти). Операционная система может делать то же самое: держать память готовой на случай, если вы захотите выделить ее снова, или пометить ее как освобожденную немедленно.
Ах да, фрагментация.
Память обычно делится на страницы. На Intel x86 и amd64 страница занимает 4 КБ. Каждая страница содержит некоторую информацию, в том числе:
Предположим, ваше приложение выделяет 16 раз по 256 байт, и вам повезло, что вся эта память размещена на одной странице размером 4 КБ. Если вы теперь освободите 15 из этих распределений, 16-е выделение сохранит выделенную страницу памяти, не давая ОС пометить ее как освобожденную. Довольно легко написать приложение, которое выделяет 1,5 ГБ, а затем освобождает 1,4 ГБ и по-прежнему потребляет 1,5 ГБ памяти (в зависимости от ОС).
Это означает, что даже если вы освободили всю память, могут быть только некоторые внутренние структуры данных времени выполнения C / C ++ или некоторые сторонние структуры данных (возможно, некоторый кэш), которые могут сохранять некоторые страницы выделенными, хотя вы полностью освободили всю свою память.
Инструменты, которые вы используете, отслеживают объем памяти, выделяемой процессом из операционной системы, они не отслеживают размер выделения памяти, в настоящее время активного в вашей программе на C ++.
Когда вы распределяете память с помощью своего кода на C ++, возможно, вам придется выйти в ОС и попросить больше. Это увеличит значения, которые вы отслеживаете.
Тем не менее, когда вы освобождаете его, есть нет требований что это даст эту память назад в ОС, так как это может понадобиться снова очень скоро.
Итак, хотя ваша программа на C ++ освободила память, C ++ среда держит его на случай, если оно понадобится снова.
Это зависит от операционной системы, но обычно, когда процесс захватывает память, он сохраняет ее. Возможно, вы не используете память, но она доступна для вашего процесса (в свободном пуле).