我目前正在做一个大规模的应用程序项目(用c++编写),这个项目是前段时间从头开始的,到了必须对内存泄漏进行一次全面检查的地步。
该应用程序运行在Ubuntu Linux上,拥有大量的多媒体内容,并使用OpenGl、SDL和ffmpeg实现了3D图形渲染、窗口、音频和电影回放。您可以将其视为视频游戏,尽管它不是,但应用程序的职责可以通过将其视为视频游戏来简化。
我现在有点不知道我们是否仍然有内存泄漏。在过去,我们已经识别了一些,并删除了它们。然而,这些天来,应用程序几乎完成了,我们运行的测试给了我一些我不能确切弄清楚的结果。
我做的第一件事是尝试通过Valgrind运行应用程序...不幸的是,当在valgrind环境中运行时,应用程序会崩溃。“非确定性”中的崩溃,因为它在不同的地方崩溃。因此,我放弃了使用Valgrind来轻松识别潜在泄漏的来源,并最终使用了两个Linux命令: free和top。
正在使用空闲空间探测应用程序运行时的系统内存使用情况
top与'-p‘选项一起使用,用于探测应用程序进程在运行时的内存使用情况。
顶部和自由格式的输出将被转储到文件中进行后处理。我用数据做了两个图表,它们在问题的底部链接在一起。
测试用例非常简单:一旦应用程序启动并等待命令,就会探测有关内存的数据。然后我启动一系列的命令,这些命令总是重复地做同样的事情。该应用程序预计会将大量多媒体数据加载到RAM中,然后下载它。
不幸的是,图表并没有显示我所期望的结果。内存使用量通过3个不同的步骤增长,然后停止。内存显然从来没有释放过,这暗示着有一个巨大的内存泄漏。这将是非常好的,因为这将意味着我们很可能不会释放被媒体内容占用的内存。
但在前三步之后...内存使用情况稳定...没有更大的台阶了..。只是稍微向上和向下,这与预期的数据加载和卸载相对应。这里意想不到的是,本应加载/卸载的数据占RAM的百分之一兆字节,而起伏只有几兆字节(比方说8-10 MB)。
我目前在解释这些数据方面相当不知所措。
谁有什么建议或建议?我遗漏了什么?我用来检查宏观内存泄漏的方法是完全错误的吗?除了Valgrind之外,您还知道其他(最好是免费的)检查内存泄漏的工具吗?
System Memory Usage Graph
Process Memory Usage Graph
发布于 2012-12-30 03:34:58
首先……
和我们达到了强制对内存泄漏进行一次全面检查的地步。
这实际上是一个方法论的问题。正确性应该是任何软件的首要目标,而不是事后才想到的。
那么,现在该怎么办呢?
- Try to make Valgrind work, you probably have some environmental issues
- Try [ASan](http://clang.llvm.org/docs/AddressSanitizer.html), [ThreadSan](http://clang.llvm.org/docs/ThreadSanitizer.html) and [MemSan](http://clang.llvm.org/docs/MemorySanitizer.html); they are not trivial to setup under Linux but oh so impressive!
- Try instrumented builds: [tcmalloc](http://goog-perftools.sourceforge.net/doc/tcmalloc.html) includes a [heap-checker](http://goog-perftools.sourceforge.net/doc/heap_checker.html) for example
- ...
- Turn on the warnings (preferably with `-Werror`) (not specific to your issue)
- Use static analysis, such as [Clang's](http://clang-analyzer.llvm.org/), it may spot unpaired allocation routines
- ...
- Code reviews: make sure all resources are allocated within RAII classes
- ...
注意:只使用RAII类有助于消除内存泄漏,但对悬空引用没有帮助。值得庆幸的是,检测悬空引用正是ASan所做的。
一旦你修补了所有的问题,确保这成为这个过程的一部分。应该始终审查和测试更改,以便立即剔除坏蛋,而不是让它弄脏代码库。
发布于 2012-12-30 01:34:38
而不是放弃Valgrind,相反,你应该与他们合作,并尝试
说你放弃了Valgrind,这是你问题的解决方案,这真的无济于事。
Valgrind是我们在linux下用来检查内存泄漏和线程问题的工具。
最后,花时间弄清楚“为什么Valgrind不适用于我的应用”肯定比寻找替代解决方案更好。Valgrind是一个经过验证和测试的工具,但并不完美。它以很大的优势击败了其他方法。
Valgrind的页面上说,最好向Bugzilla提交bug,但实际上更好的做法是在https://lists.sourceforge.net/lists/listinfo/valgrind-users上询问是否有人以前见过这样的问题,以及在这种情况下该怎么做。最坏的情况--他们会告诉你把bug提交给bugzilla或者自己提交。
发布于 2012-12-30 01:28:37
你可能想看看valgrind。
您可能只想从非常简单的示例开始,以了解valgrind报告的内容,这可能会有点冗长。考虑这个简化的示例,其中valgrind准确地缺少了什么和多少:
edd@max:/tmp$ cat valgrindex.cpp
#include <cstdlib>
int main() {
double *a = new double[100];
exit(0);
}
edd@max:/tmp$ g++ -o valgrindex valgrindex.cpp
edd@max:/tmp$ valgrind ./valgrindex
==15910== Memcheck, a memory error detector
==15910== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==15910== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==15910== Command: ./valgrindex
==15910==
==15910==
==15910== HEAP SUMMARY:
==15910== in use at exit: 800 bytes in 1 blocks
==15910== total heap usage: 1 allocs, 0 frees, 800 bytes allocated
==15910==
==15910== LEAK SUMMARY:
==15910== definitely lost: 0 bytes in 0 blocks
==15910== indirectly lost: 0 bytes in 0 blocks
==15910== possibly lost: 0 bytes in 0 blocks
==15910== still reachable: 800 bytes in 1 blocks
==15910== suppressed: 0 bytes in 0 blocks
==15910== Rerun with --leak-check=full to see details of leaked memory
==15910==
==15910== For counts of detected and suppressed errors, rerun with: -v
==15910== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
edd@max:/tmp$ https://stackoverflow.com/questions/14084151
复制相似问题