C ++,泄漏与否?可以做些什么

时间:2016-09-22 14:44:37

标签: c++ memory-management memory-leaks valgrind

我们有一个程序在运行很长一段时间后由于内存不足而崩溃在4Gb。 该项目采用C ++,openSuse11,12,包括链接到各种共享内存和其他库。

从PID的pmap监视堆增加和总内存增加,它们完全类似。这意味着该过程从2.5Gb和堆〜0开始,然后在崩溃Total = 4 Gbheap = 1.5 Gb之前。

我们用valgrind进行了一些运行,结果非常令人费解。下面你可以看到运行20分钟的摘要。

==30042== HEAP SUMMARY:
==30042==     in use at exit: 706,413 bytes in 3,345 blocks
==30042==   total heap usage: 1,770,240 allocs, 1,766,895 frees, 173,813,303 bytes allocated

==30042== LEAK SUMMARY:
==30042==    definitely lost: 96 bytes in 3 blocks
==30042==    indirectly lost: 27 bytes in 3 blocks
==30042==      possibly lost: 344 bytes in 2 blocks
==30042==    still reachable: 705,946 bytes in 3,337 blocks
==30042==                       of which reachable via heuristic:
==30042==                         stdstring          : 62 bytes in 2 blocks
==30042==         suppressed: 0 bytes in 0 blocks

监控pmap,我们知道总内存增加130 Mb但是将其与valgrind报告进行比较,我们可以看到有泄漏,但没有真正接近130 Mb

现在回答问题:

  • 有人可以帮我理解valgrind摘要以及它与130 Mb丢失的关系吗?

  • 这是否泄漏?

  • valgrind是否会报告内部情况 共享的回忆?
  • 即使SM中有泄漏,也不会 还在堆里吗?它们的尺寸合理。
  • 我已经阅读了各种来源,即使用delete[] or free()释放内存,系统仍然可以为将来保留空间 使用。如果是这样的话,可以做些什么?

* EDIT 这个堆使用似乎不受限制的地方是当作为服务器的程序连续调用大数据的DB(实心SQL)时,它会分配大量空间。它不在共享内存中。我们发现可以正确管理免费,可以做些什么?

1 个答案:

答案 0 :(得分:1)

看看Valgrind套件中的Massif工具。堆分析器将帮助您了解程序如何继续增长而不受限制。无限增长似乎是问题而不是泄漏。

  

有人可以帮助我理解valgrind摘要以及它是如何做到的   与丢失的130万亿有关?

Valgrind表示该程序使用了170mb的堆,这与你的数字相差不远。较长的运行可能会显示不断增加的最大堆大小。

  

这是否是泄漏?

报告没有说明泄漏的方式。看起来程序清理得很好。峰值堆使用似乎是个问题。

  

valgrind是否会报告共享内存中的内容?

不,Valgrind会查看本地进程的堆内存。

  

即使SM中存在泄漏,它也不会在堆中   他们?它们的尺寸合理。

不,共享内存不是堆内存。 ipcs和其他工具可以显示正在使用的共享内存量。 32位进程的总可寻址空间为4gb,因此映射到进程的共享内存量可以减少可用的堆空间量。

  

我已经阅读过各种来源,即使在释放内存时也是如此   delete []或free()系统仍然可以保留空间   未来的使用。如果是这样的话,可以做些什么?

是的,这是准确的。一旦将内存分配给进程,它将不会返回到操作系统,直到进程退出。堆将在进程中重复使用,因此除非实际使用,否则堆的最大大小不会增加。在用户级别无法做任何事情,通常这不是问题。

重申一下,程序中的数据结构可能会不受限制地增长。例如,一个无限添加的链表。由于数据仍然可以访问,因此从技术上讲这不是泄漏,也不会显示在valgrind报告中。堆分析器(如Massif)可以指向源代码中分配大量堆内存的区域。