2014-03-19 47 views
0

我有一个无限期增长的内部C++应用程序 - 以至于我们不得不实施逻辑,一旦RSS达到一定的峰值大小(2.0G)只是为了保持一定的秩序。但是,这已经显示出一些奇怪的行为。内存泄漏不会在OOM时崩溃,或者在massif/valgrind中显示

首先,我通过Valgrind w/memcheck运行应用程序,并在这里和那里修复了一些随机内存泄漏。但是,这些内存泄漏的程度是以兆字节为单位测量的。这是有道理的,因为它可能没有实际的内存泄漏 - 它可能只是应用程序方面的内存管理不善。

接下来,我使用Valgrind w/massif来检查内存在哪里,这就是奇怪的地方。峰值快照为161M - 远不及我们使用RSS字段看到的1.9G +峰值。最大的消费是我期望的地方 - 在std :: string中 - 但这不是不正常的。

最后,这是最令人困惑的 - 在我们意识到这种内存泄漏之前,我实际上是在AWS上测试这个服务,并且为了好玩,在CC2上将工作者数量设置为很高的数量。 8XL机器,44名工人。这是60.5G的RAM,并没有交换。快进一个月:我去看看主机 - 低,看,它已经超出RAM - 但!这些进程仍然运行良好,并且停留在不同的内存使用阶段 - 几乎均匀分布在800M到1.9G之间。每隔一段时间dmesg就会打印出关于无法分配内存的Xen错误,但除此之外,进程永远不会停止并继续进行主动处理(即它们不会“卡住”)。

有什么我在这里失踪?它基本上是在工作,但对于我的生活,我无法弄清楚为什么。接下来要寻找什么会是一个好的建议?有没有什么工具可以帮我弄明白?

回答

1

请注意,valgrind memcheck只会在您“放弃”内存时发现。 while(1) vec.push_back(n++);将填充所有可用内存但不报告任何泄漏。从事物的声音来看,你正在收集占据大量空间的字符串。我也研究过使用大量内存但没有真正泄漏的代码[这些都是valgrind开心的不是漏洞!]。有时候你可以通过简单地将一些标记添加到内存分配中来追踪它,或者一些这样的标记来指示你在分配内存的位置。

std::函数中,通常有一个参数Allocator。如果你实现了几个不同的内存池,你可能会发现你在哪里分配内存。

我也看到了一些情况,我认为这个过程是内存碎片化的,所以堆中有很多小的空闲空间 - 例如,如果您通过添加以创建大量字符串字符串的大小。

+0

地块应该告诉我,如果这种记忆是膨胀的,但是,它不应该?也就是说,我有一些愚蠢的循环,只是将20个指针附加到一个长寿命的向量上,每个循环都有一个20MB内存的新块。我希望地块表明我只分配了400MB的内存 - 你知道这是真的吗? – Redmumba

+0

它应该,除非代码使用非标准分配(例如,它使用'mmap'或类似的分配器来分配大内存)。这将是相当容易的证明,用10行代码,我会说... –

+0

代码不使用自定义分配器,我通过cachegrind输出证实了这一点。我确实发现,矢量调整大小非常巨大--45亿次调用 - 可能有助于内存分配。 – Redmumba