简体   繁体   English

如何使用进程的 memory 用法检查 memory 泄漏?

[英]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] = '\0'; // 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;
}

I'm trying to check memory leaks but I don't understand physical memory and virtual memory clearly.我正在尝试检查 memory 泄漏,但我不清楚物理 memory 和虚拟 memory。 So I just printed both using the functions above.所以我只是使用上面的功能打印了两个。

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;

If I check the changes of physical memory or virtual memory, which one should I take a look at?如果我查看物理memory或虚拟memory的变化,我应该看哪一个? Both?两个都? or one of them?还是其中之一?

And I found that even if there are no memory leaks the memory values are changed.而且我发现即使没有 memory 泄漏,memory 值也会发生变化。

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;
}

After an hour of running the code above, it showed the changes in the memory运行上面的代码一个小时后,它显示了 memory 中的变化

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

So is this method fine to check memory leak or not?那么这种方法是否可以检查 memory 是否泄漏? I used "Valgrind" but it didn't show any memory leak message from my code(not the above code. It is too huge to upload here. It is over 30000 lines.).我使用了“Valgrind”,但它没有显示我的代码中的任何 memory 泄漏消息(不是上面的代码。它太大了,无法在此处上传。超过 30000 行。)。 But it showed memory changes in the long-term running test(about 1-week).但它在长期运行测试(约1周)中显示memory变化。

Please let me know how to check memory leaks correctly without using other software(such as Valgrind).请告诉我如何在不使用其他软件(如 Valgrind)的情况下正确检查 memory 泄漏。

If I understand you correctly you want to check for memory leaks on Linux using a process image from an process that has not been instrumented in any way.如果我对你的理解正确,你想使用来自未以任何方式检测的进程的进程映像来检查 Linux 上的 memory 泄漏。

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

First you gather a core:首先你收集一个核心:

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

Then you open the core in chap:然后你在章节中打开核心:

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

To check for the classic kind of leak (objects that can no longer be reached) you can use the following commands from the chap prompt:要检查经典类型的泄漏(无法再到达的对象),您可以在 chap 提示符下使用以下命令:

count leaked

That tells you how many objects were leaked.这告诉你有多少对象被泄露了。

describe leaked /showUpTo 100

That describes each leaked object, gives a hex dump of up to 0x100 bytes of each object and gives you the count at the end.这描述了每个泄漏的 object,给出了每个 object 的最多 0x100 字节的十六进制转储,并在最后给出了计数。

Various other commands are available but I don't want to repeat the user's manual.还有各种其他命令可用,但我不想重复用户手册。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM