我已经在一个大型项目中使用 tcmalloc 几个月了,到目前为止,我必须说我对它非常满意,最重要的是它的 HeapProfiling 功能允许跟踪内存泄漏并删除它们。
在过去的几周里,虽然我们在应用程序中遇到了随机崩溃,但我们找不到随机崩溃的根源。在一个非常特殊的情况下,当应用程序崩溃时,我们发现自己的某个应用程序线程的堆栈完全损坏。有几次我发现线程卡在 tcmalloc::PageHeap::AllocLarge() 中,但由于我没有链接 tcmalloc 的调试符号,我无法理解问题所在。
经过近一周的调查,今天我尝试了最简单的事情:从链接中删除tcmalloc以避免使用它,只是为了看看发生了什么。嗯...我终于发现了问题所在,并且有问题的代码看起来很像这样:
void AllocatingFunction()
{
Object object_on_stack;
ProcessObject(&object_on_stack);
}
void ProcessObject(Object* object)
{
...
// Do Whatever
...
delete object;
}
使用 libc 应用程序仍然崩溃,但我终于看到我正在对分配在堆栈上的对象调用 delete。
我仍然无法弄清楚为什么 tcmalloc 会保持应用程序运行,而不管这种非常危险(如果不是完全错误)的对象释放,以及当 AllocatingFunction 结束时 object_on_stack 超出范围时的双重释放。事实是,可以重复调用有问题的代码,而没有任何潜在可憎的暗示。
我知道如果使用不当,内存释放是那些“未定义的行为”之一,但令我惊讶的是“标准”libc 和 tcmalloc 之间的行为如此不同。
有没有人对为什么 tcmalloc 保持应用程序运行有某种洞察力的解释?
提前致谢 :)
祝你今天过得愉快