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

How to remove memory leak in Qthreads? 12+Gb leak

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

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

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

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

遵循此建议 () 我阻止了 QThread 的子类化和实现 运行().

这是一个 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];
    }

and NULL for all points before cntrl[cnt2%arrSize]

没有变化

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

2个问题导致泄漏:

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

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

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