c ++中的内存泄漏

时间:2009-04-20 08:30:06

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

我在intel Xscale设备上运行我的c ++应用程序。问题是,当我使用Valgrind运行我的应用程序offtarget(Ubuntu)时,它不会显示任何内存泄漏。

但是当我在目标系统上运行它时,它以50K可用内存开始,并在一夜之间减少到2K。如何捕捉这种泄漏,这是Valgrind没有显示的?

9 个答案:

答案 0 :(得分:10)

这些小型嵌入式deviecs的常见罪魁祸首是内存碎片。您的应用程序可能在两个对象之间有可用内存。对此最常见的解决方案是为最常见的类使用专用分配器(C ++中的operator new)。纯粹用于大小为N的对象的内存池不会碎片化 - 两个对象之间的空间总是N的倍数。

答案 1 :(得分:3)

这可能不是泄漏,而只是运行时堆不向操作系统释放内存。这也可能是碎片化。

克服这个问题的可能方法:

  1. 分成两个应用程序。主应用程序将具有简单的逻辑,很少或没有动态内存使用。它将启动worker应用程序实际上以这样的块工作,即worker应用程序不会耗尽内存并定期重启该应用程序。这样,内存会定期返回给操作系统。

  2. 编写自己的内存分配器。例如,您可以分配专用堆并仅从那里分配内存,然后完全释放专用堆。这要求操作系统支持多个堆。

  3. 另请注意,您的程序可能在Ubuntu和目标系统上运行不同,因此会采用不同的执行路径,导致内存泄漏的代码在目标系统上执行,但不会在Ubuntu上执行。

答案 2 :(得分:3)

它可能不是实际的内存泄漏,但可能是内存使用量增加的情况。例如,它可能会分配一个不断增加的字符串:

string s;
for (i=0; i<n; i++)
  s += "a";

50k并不是那么多,也许你应该手工检查你的来源,看看可能导致这个问题的原因。

答案 3 :(得分:1)

这听起来像碎片。碎片是由您在堆栈上分配对象引起的,例如:

object1
Object2的
object3
object4

然后删除一些对象

object1

object3
object4

你现在在内存中有一个未使用的洞。如果你为孔分配另一个太大的物体,那么这个孔将会被浪费掉。最终,如果有足够的内存流失,你可能会遇到很多漏洞而浪费你的记忆。

解决这个问题的方法是先尝试决定你的记忆要求。如果你有特定的对象,你知道你正在创建许多对象,请尝试确保它们的大小相同。

您可以使用池来使分配对特定类更有效...或者至少让您更好地跟踪它,以便您可以了解正在发生的事情并提出一个好的解决方案。

这样做的一种方法是创建一个静态:

struct Slot
{
    Slot() : free(true) {}
    bool free;
    BYTE data[20];  // you'll need to tune the value 20 to what your program needs
};
Slot pool[500]; // you'll need to pick a good pool size too.

在程序启动时预先创建池并预先分配它,使其与程序的最大需求一样大。您可能想要HeapAlloc它(或者您的操作系统中的等效文件,以便您可以控制它何时从应用程序启动中的某个位置出现)。

然后覆盖可疑类的new和delete运算符,以便它们从此向量返回槽。因此,您的对象将存储在此向量中。

您可以覆盖相同大小的类的new和delete,以放入此向量中。

为不同的对象创建不同大小的池。

首先去找最坏的罪犯。

之前我做过类似的事情,它解决了我在嵌入式设备上遇到的问题。我也使用了很多STL,所以我创建了一个自定义分配器(google for stl custom allocator - 有很多链接)。这对于我的程序使用的迷你数据库中存储的记录非常有用。

答案 4 :(得分:0)

如果您的内存使用率下降,我认为它不能被定义为内存泄漏。 你在哪里得到内存使用情况的报告?系统可能只是将程序的大部分内存用在虚拟内存中。

我可以补充的是,Valgrind在查找内存泄漏方面非常有效!

答案 5 :(得分:0)

另外,您确定在分析代码时,代码覆盖率是否足以覆盖可能在目标平台上执行的所有代码路径?

Valgrind肯定不会撒谎。正如已经指出的那样,这可能确实是运行时堆没有释放内存,但我认为不是这样。

答案 6 :(得分:0)

您是否正在使用任何复杂的技术来跟踪对象的范围..? 如果是的话,比valgrind不够聪明,虽然你可以尝试通过与valgrind设置xscale相关的选项

答案 7 :(得分:0)

大多数应用程序都显示了这样的内存使用模式:

  • 他们开始时使用很少
  • 因为他们创建了越来越多的数据结构
  • 当他们开始删除旧数据结构或重用现有数据结构时,它们会达到稳定状态,即内存使用大致保持不变

如果您的应用程序的大小持续增加,您可能会遇到麻烦。如果它在一段时间内增加了sizze然后达到相对稳定的状态,你可能不会。

答案 8 :(得分:0)

您可以使用Valgrind的massif工具,它将显示分配最多内存的位置以及它随时间的演变情况。