我用valgrind检查代码,没有内存泄漏。
但我使用的是顶级'要查看内存,在删除'之后会花费295MB内存。调用。
我使用' pmap -x'通过[anon]来查看内存,大部分内存成本:
Address Kbytes RSS Dirty Mode Mapping
0000000001114000 301672 301588 301588 rw--- [ anon ]
我不知道为什么记忆已被释放,但它的成本仍为295MB。谁知道为什么?
#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();
}
答案 0 :(得分:0)
您正在使用的工具是监视进程从操作系统分配的内存,它们不监视C ++程序中当前活动的内存分配的大小。
当您使用C ++代码分配内存时,可能需要转到操作系统并要求更多内容。这将增加您正在监控的值。
但是,当你释放它时,没有要求将内存返回提供给操作系统,因为它很快就会再次需要它。
因此,即使您的C ++程序已经释放了内存,C ++ 环境也会保留它,以防您再次需要它。
答案 1 :(得分:0)
这是特定于操作系统的,但通常一旦进程抓住内存就会保留它。您可能没有使用内存,但它可用于您的进程(在空闲池中)。
答案 2 :(得分:0)
缓存,缓存,缓存。哦,是的,和碎片。
通过不同的层分配内存。如果您的应用程序分配内存,它将询问它到C / C ++运行时。 C / C ++运行时将检查自己的数据结构是否有可用内存,如果它没有,它会将调用转发给操作系统。根据C / C ++运行时(和版本),C / C ++运行时数据结构可能很广泛,或者C / C ++运行时可能只是直接将调用转发给OS。对于Microsoft Visual Studio(此刻不使用Linux,抱歉),我知道:
这意味着当释放内存时,C / C ++运行时可能决定保留内存(出于多种原因,包括如果您决定再次分配内存则能够更快地返回内存),或者可能将其返回到操作系统(如果它已经有很多空闲内存)。操作系统可能完全相同:保留内存,以备再次分配,或将其标记为已立即解除分配。
哦,是的,碎片化。 内存通常分为页面。在Intel x86和amd64上,页面为4KB。每个页面都包含一些信息,包括:
假设您的应用程序分配16次256字节,并且您很幸运,所有这些内存都分配在一页4KB内。如果您现在释放其中的15个分配,则第16个分配将保留分配的内存页,从而阻止操作系统将其标记为已释放。编写一个分配1.5GB的应用程序,然后释放1.4GB的内存,并且仍然消耗1.5GB的内存(根据操作系统),这很容易。
这意味着即使您释放了所有内存,也可能只有一些内部C / C ++运行时数据结构,或者某些第三方数据结构(可能是某些缓存)可能会保留一些页面,尽管您完全取消了所有内容你的记忆。