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

C++, Leak or not? what can be done

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

从PID的pmap看heap增加和total memory增加,完全类比。这意味着该进程以 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

现在回答问题:

*EDIT 这个堆使用似乎不受限制的地方是当作为服务器的程序调用数据库(固体SQL)进行大数据源源不断,分配了很多space。它不在共享内存中。我们看到免费管理正确,可以做什么?

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

Can someone help me understand the valgrind summary and how it can relate to the 130 Mb lost ?

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

Is this a leak or not ?

该报告并未表明泄漏的方式。看来该程序清理得很好。峰值堆使用量似乎是个问题。

Does valgrind report what is going on inside the shared memories ?

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

Even if there is a leak in the SM, wouldn't it still be in heap in them? Their sizes are in reasonable levels.

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

I have read in various sources, that even when freeing the memory with delete[] or free() the system still may keep the space reserved for future use. If that is the case, what can be done ?

是的,这是准确的。一旦内存被分配给一个进程,它就不会返回到 OS 直到进程退出。堆将在进程中重复使用,因此除非实际使用,否则堆的最大大小不会增加。在用户级别无能为力,通常这不是问题。

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