一周以来竟然碰到两个内存方面的"潜规则",折腾了不少时间。
写出来希望对各位看客有帮助。
一. 微软的潜规则 DLL内动态申请的堆,必须在DLL内释放掉
DLL 函数
// 在DLL内申请内存堆
void* _dll_malloc(size_t size )
{
void* mem = malloc(size);
return mem;
}
{
void* mem = malloc(size);
return mem;
}
//在DLL内释放内存堆
void _dll_free(void* mem)
{
free(mem);
}
{
free(mem);
}
main 函数
int main(int argc, char* argv[])
{
{
//使用DLL函数申请内存堆
char* mem = (char*)_dll_malloc(32);
//使用申请的内存
strncpy(mem,"hello,world",32);
std::cout<<mem<<std::endl;
strncpy(mem,"hello,world",32);
std::cout<<mem<<std::endl;
//释放的内存
free(mem); // 此语句有exception
return 0;
}
free(mem); // 此语句有exception
return 0;
}
运行结果:
hello,world
然后,跳出一个巨大的exception对话框。
问题很明显,这里遭遇微软潜规则:dll模块申请的内存,只能在dll函数中释放。 理由是dll和main函数使用不同的堆云云...
怎么办?不释放肯定会导致内存泄露。
解决问题有:
1. 在dll内定义一个 void _dll_free(void* mem) 函数对库函数free进行包装,在main函数中使用这个函数对内存进行释放。程序运行完全正常
int main(int argc, char* argv[])
{
{
//使用DLL函数申请内存堆
char* mem = (char*)_dll_malloc(32);
//使用申请的内存
strncpy(mem,"hello,world",32);
std::cout<<mem<<std::endl;
strncpy(mem,"hello,world",32);
std::cout<<mem<<std::endl;
//释放的内存
_dll_free(mem); // 释放成功
return 0;
}
_dll_free(mem); // 释放成功
return 0;
}
2. main函数申请内存,把指针传给dll使用,在main中释放。
3. 使用全局 GlobalAlloc/GlobalFree 函数进行分配
4. dll函数返回一个结构 struct mem_block { data[1024] } ; 等等。
二, Python潜规则:申请的内存,我从不交还操作系统,直至程序退出。
问题描述:
在python中使用list对象,不断往list中添加对象,直到使用的内存达到1G;
然后,不断使用list中的对象,使用一个删除一个,期望python占用的内存会不断减少。
结果:
python一直占据内存使用的峰值1G
使用各种方法,del , gc.collect() 完全无效。python就是牛,就是要一直占据着它碰过的东西,谁也不许动。
TMD