如何使用进程的内存使用情况检查内存泄漏?

How to check memory leaks using memory usages of a process?

int ParseLine(char* line){
   int i = strlen(line);
   const char* p = line;
   while(*p < '0' || *p > '9') p++;    // Search until a number is found.
   line[i - 3] = '[=10=]'; // Remove " kB"
   i = atoi(p);
   return i;
}

int GetCurrentVirtualMem(){
   std::string cur_proc;
   cur_proc = "/proc/" + std::to_string((int)getpid()) + "/status";

   FILE* fs = fopen(cur_proc.c_str(), "r");
   int result = -1;
   char line[128];

   while(fgets(line, 128, fs) != NULL){
       if(strncmp(line, "VmSize:", 7) == 0){
           result = ParseLine(line);
           break;
       }
   }
   fclose(fs);
   fs = NULL;  //garly modify, for test memory problem

   return result;
}

int GetCurrentMem(){
   std::string cur_proc;
   cur_proc = "/proc/" + std::to_string((int)getpid()) + "/status";

   FILE* fs = fopen(cur_proc.c_str(), "r");
   int result = -1;
   char line[128];

   while(fgets(line, 128, fs) != NULL){
       if(strncmp(line, "VmRSS:", 6) == 0){
           result = ParseLine(line);
           break;
       }
   }
   fclose(fs);
   fs = NULL;  //garly modify, for test memory problem
   return result;
}

我正在尝试检查内存泄漏,但我不清楚物理内存和虚拟内存。所以我只是使用上面的函数打印了两个。

float curr_mem = (float)GetCurrentMem() / 1000;
float curr_vir_mem = (float)GetCurrentVirtualMem() / 1000;
std::cout << "Using memory(" << std::to_string((int)getpid()) << "): " << curr_mem << ", " << curr_vir_mem << std::endl;

如果我查看物理内存或虚拟内存的变化,我应该看哪一个? 两个都?还是其中之一?

而且我发现即使没有内存泄漏,内存值也会发生变化。

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);

   float prev_mem = 0;
   float prev_vir_mem = 0;
   while(true){

       int* mem_leak = new int[100];


       float curr_mem = (float)GetCurrentMem() / 1000;
       float curr_vir_mem = (float)GetCurrentVirtualMem() / 1000;

       if(prev_mem != curr_mem || prev_vir_mem != curr_vir_mem){
           prev_mem = curr_mem ;
           prev_vir_mem = curr_vir_mem;

           std::cout << "Using memory(" << std::to_string((int)getpid()) << "): " << curr_mem << ", " << curr_vir_mem << std::endl;
       }

       delete[] mem_leak;
   }
   return 0;
}

经过一个小时运行上面的代码,它显示了内存中的变化

Using memory(3303): 28.296, 250.788 
Using memory(3303): 28.652, 250.788 
Using memory(3303): 28.916, 250.788

那么这种检查内存泄漏的方法好不好? 我使用了“Valgrind”,但它没有显示我的代码中的任何内存泄漏消息(不是上面的代码。它太大了,无法在此处上传。超过 30000 行。)。但它显示了长期 运行 测试(大约 1 周)的记忆变化。

请告诉我如何在不使用其他软件(例如Valgrind)的情况下正确检查内存泄漏。

如果我对你的理解是正确的,你想检查 Linux 上的内存泄漏,使用来自未以任何方式检测的进程的进程映像。

https://github.com/vmware/chap(免费开源)就是这样做的。

首先你要收集一个核心:

echo 0x37 > /proc/<pid-of-your-process>/coredump_filter
gcore <pid-of-your-process>

然后你在章节中打开核心:

chap <core-just-created-by-gcore>

要检查典型类型的泄漏(无法再到达的对象),您可以在 chap 提示符下使用以下命令:

count leaked

这告诉你有多少对象被泄露了。

describe leaked /showUpTo 100

它描述了每个泄漏的对象,给出了每个对象最多 0x100 字节的十六进制转储,并在末尾给出了计数。

还有各种其他命令可用,但我不想重复用户手册。