如何消除Qthreads中的内存泄漏? 12 + Gb泄漏

时间:2015-07-23 16:45:43

标签: c++ multithreading performance qt memory-leaks

我正在尝试加速我的(qt c ++ opencv)程序,该程序应该计算我的照片中的颜色数量,以便将来过滤。 单线程方法没有泄漏,但速度非常慢。

通过添加8个线程,我已经将此过程加速了5倍。

当我将程序切换到多线程时,问题就开始了。

存在巨大的内存泄漏! http://snag.gy/cHRrS.jpg

遵循此建议(https://stackoverflow.com/a/12859444) 我阻止了继承QThread并实现run()。

这是一个for循环,用于计算每个移位1个像素的新图像中的每个像素:

ColorCounterController *cntrl[arrSize];

for (int i = 0; i < box; i++)//x
{
    for (int j = 0; j < box; ++j)//y
    {
        cv::Mat res=process(image,i,j);


        //Using 1 core
        //colors=ColorDetectController::getInstance()->colorsCount(res);

        //Using all 8 cores
        cntrl[cnt2%arrSize]= new ColorCounterController(res,this);

        ++cnt2;
    }

    ++cnt;
    emit setStatusProgressSignal((int)(cnt/amnt*100));
}

delete[] *cntrl;

评论:

当使用1核(上面的代码)时,我有单例来运行colorsCount(res)函数。 在8核的情况下,我使用几乎相同的功能,但从ColorCounterController调用。

class ColorCounterController : public QObject{
Q_OBJECT
private:
QThread thread;
ColorCounter *colorCntr;
Pixalate *pixelate;
private slots:
void freecolorCntr(){
    delete colorCntr;
}
public:
ColorCounterController(const cv::Mat &image,Pixalate *pxobj) {
    colorCntr= new ColorCounter();
    colorCntr->setimageThread(image);
    colorCntr->moveToThread(&thread);
    connect(&thread, SIGNAL(started()), colorCntr, SLOT(colorsCountThread()));
    connect(colorCntr, SIGNAL(finished()), &thread, SLOT(quit()));
    connect(colorCntr, SIGNAL(finished()), colorCntr, SLOT(deleteLater()));
        connect(colorCntr, SIGNAL(results(int)), pxobj, SLOT(results(int)));
    thread.start();
}

    ~ColorCounterController() {
    thread.quit();
    thread.wait();
     qDebug() << QString("Controller quit wait");
    //delete colorCntr; //err
}

我认为泄漏在ColorCounterController构造函数中:

        colorCntr= new ColorCounter();

但如何避免呢?此代码导致错误。 在析构函数中:

//delete colorCntr; //err

并在构造函数中:

//connect(&thread, SIGNAL(finished()), &thread, SLOT(deleteLater()));

请帮忙!

P.S。

我改变了这个

delete[] *cntrl;

到这个

    for (int i = 0; i < arrSize; i++){
    if (cntrl[i])
        delete cntrl[i];
    }
cntrl之前的所有指针的

和NULL [cnt2%arrSize]

没有任何改变

P.P.S。 如果您想为此问题做出贡献: https://github.com/ivanesses/curiosity

1 个答案:

答案 0 :(得分:1)

2个问题导致泄漏:

  1. 新ColorCounterController对象的指针将永远丢失(并且它们的内存泄漏),因为“for”循环的主体将运行N次(N = box * box),创建N个ColorCounterController对象但仅指向8它们将适合您稍后用于删除对象的数组。

  2. cntrl是一个指针数组。你需要遍历它并在每个元素上调用delete(plain delete,而不是delete [])。

  3. 由OP发现的
  4. :必须使用imageThread.release();而不是imageThread.deallocate()