TBB可能存在内存泄漏问题。

5

测试程序:

#include <tbb/parallel_invoke.h>

int main(void)
{
    tbb::parallel_invoke([]{},[]{});
    return 0;
}
  1. Compiled using g++ -std=c++11 tmp.cpp -ltbb
  2. Checked with

    valgrind --tool=memcheck --track-origins=yes \
             --leak-check=full --log-file=report ./a.out`
    
  3. libtbb version: 4.0, valgrind version: 3.8.1.

以上测试结果的一部分:

possibly lost: 1,980 bytes in 6 blocks

问题是:

这是一个 TBB 的 bug 吗?

还是这个 possible lost 实际上是安全的,只是一些代码 valgrind 认为不安全?


当我使用tbb时,我也遇到了内存泄漏的问题。 - Alex VII
同样的问题,但只是自从我升级TBB到4.3版本后才出现。在4.2版本中没有泄漏问题。我使用VLD检测泄漏。我怀疑当调度程序结束运行时,任务根本没有被销毁。 - Klaim
TBB肯定存在内存泄漏问题:请参见http://stackoverflow.com/questions/19273543/tbb-memory-leaks-when-using-inside-of-mfc-application - gast128
1个回答

2

很可能这只是一个误报,而不是一个错误。至少有以下几个原因:

  1. TBB使用自己的内存分配器 libtbbmalloc,它会缓存内存直到进程终止并且可能会被视为泄漏。
  2. TBB线程异步运行和终止。在 main() 终止后,工作线程仍在运行,这可能导致 valgrind 确认为存在泄漏。

为了合理地指责 TBB 泄漏,排除上述因素,例如:

  1. 删除 libtbbmalloc.so.2 或 tbbmalloc.dll 文件,以便使用 env.variable TBB_VERSION=1 运行应用程序将输出 TBB: ALLOCATOR malloc 而不是 TBB: ALLOCATOR scalable_malloc
  2. 确保所有 TBB 线程已终止

例如:

int main()
{
    assert(tbb::tbb_allocator<int>::allocator_type() != tbb::tbb_allocator<int>::scalable);
    { // TBB scope
        tbb::task_scheduler_init scope;
        tbb::parallel_invoke([]{},[]{});
    } // TBB threads start termination here
    sleep(10); // wait for threads to terminate
    return 0;
}

在不会通过代码审查的环境中,如果在主函数末尾插入 sleep(10) 怎么办?是否有解决此问题的方法,使我能够同时使用TBB和valgrind,但又不需要使用 sleep(10) ?例如,有没有一些方法可以要求TBB阻塞,直到所有工作线程都干净地关闭? - Quuxplusone
1
这是诊断问题的方式,当然不能在生产环境中使用。 - Anton
@Quuxplusone,有一个预览功能可以等待线程终止。因此,如果 sleep() 解决了问题,您可以考虑使用 tbb::task_scheduler_init 的阻塞终止功能来实现相同的效果,而无需使用 sleep()。 - Anton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接