我调试了一个奇怪的内存问题:当多线程算法循环运行时,尽管GooglePerformanceTools的堆检查器表示没有泄漏,但每次迭代都会增加内存消耗。最后,我制作了一个单独的最小程序来重现该错误。似乎线程是问题所在:

#include <stdio.h>
#include <iostream>
#include <vector>
#include "tinythread.h"
using namespace std;


int a(0);
void doNothingAtAll(void*)
{
    ++a;
}

void startAndJoin100()
{
    vector<tthread::thread*> vThreads;
    for(int i=0;i<100;++i)
    {
        vThreads.push_back(new tthread::thread(doNothingAtAll,NULL));
    }
    while(!vThreads.empty())
    {
            tthread::thread* pThread(vThreads.back());
            pThread->join();
            delete pThread;
            vThreads.pop_back();
    }
}

int main()
{
    for(int i=0;i<10;++i)
    {
        cout<<"calling startAndJoin100()"<<endl;
        startAndJoin100();
        cout<<"all threads joined"<<endl;
        cin.get();
    }
    return 0;
}


main()调用10次startAndJoin100()。每次迭代后,它都等待一次按键,这样就可以占用以下内存消耗(在Ubuntu 17.10下,64位):

VIRT
2.1 GB
4 GB
5.9 GB
7.8 GB
9.6 GB
11.5 GB
13.4 GB
15.3 GB
17.2 GB
19.0 GB


注意:不能使用C ++ 11,并且该程序必须在Linux和Windows上编译,因此使用了tinythread。使用Makefile的最少测试代码:
geom.at/_downloads/testTinyThread.zip

最佳答案

我回答我自己的问题,这对以后的某个人可能有用:

结论:

1)我真的很想保留TinyThread,因为C ++ 11不可用(必须支持VS2008和旧的Linux系统),并且不应该链接任何其他库(TinyThread仅由* .h和* .cpp文件组成,而Boost则由和我知道的其他解决方案需要链接DLL)。

2)Valgrind和GooglePerformanceTools的堆检查器没有报告内存泄漏,我已经研究了代码-尽管上面发布的最小示例中的虚拟内存消耗急剧增加,但这似乎是正确的。看来系统没有重新使用以前分配的内存页,并且我还没有找到有关此行为的解释。因此,我不怪TinyThread ++,但是当直接使用pthreads时它可以工作。

3)解决方法:有一个名为TinyCThread的C替代品:https://tinycthread.github.io/也适用于C ++,并且不会导致TinyThread ++出现问题。

关于c++ - 线程的内存问题(tinythread,C++),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48074235/

10-11 15:25