我一直在调查Red Hat Enterprise Linux 6上的客户问题。我也看到过类似Ubuntu的行为。客户通过输出/ proc / self / status来跟踪内存使用情况
当使用特定的ODBC驱动程序时,这在ODBC应用程序中发生,但我怀疑这与问题相关。
在程序的各个阶段跟踪内存使用情况(通过调用/ proc / self / status函数粘贴在程序的各个阶段),一次在堆上分配一些内存之后,一次在释放内存之后,一次在卸载动态库之后。
当分配的内存量超过某个值时,VmRSS在释放内存后不会立即关闭,但在卸载so文件后会立即关闭。当分配的内存量很小时,VmRSS在释放内存后立即关闭。
我在应用程序上运行valgrind,我找不到任何内存泄漏。任何帮助,解释,文章指针非常感谢。
void print_proc_status_vm()
{
std::ifstream proc_status_fhandle;
proc_status_fhandle.open("/proc/self/status");
std::string s;
int line=0;
static std::map<std::string, int> memoryUsage;
while(std::getline(proc_status_fhandle, s)){
++line;
if( (line >=12) and (line <=17 ) and (line !=14) )
{
char* str = new char[s.size()+1];
strcpy(str, s.c_str());
std::string key(strtok(str, "\t "));
int value = atoi(strtok(NULL, "\t "));
printf("%s %d \n", key.c_str(), value - memoryUsage[key] );
memoryUsage[key] = value;
delete[] str;
}
}
}
一旦我遇到了与suricata相似的问题 - 这个程序有很多小规则加载到内存中,一旦开发人员添加动态重载规则,程序最终会占用内存的两倍,即使之前的所有规则都是加载新的后释放。
这是因为有很多规则,每个规则有一个malloc,但每个都没有太多空间=> malloc内部使用brk / sbrk(类似堆栈)而不是mmap =>因为原始规则在下面数据段上的新段,即使释放了数十亿的原始规则,该段也没有减少。
在这种情况下,解决方案是一次分配一大块内存,然后手动将其拆分为更小的部分。
对于文件,它是mmapped,因此在取消映射后可以立即释放内存。