Огромная утечка памяти в opencv

0

Я написал очень простую C++ программу для чтения 600 видеокадров в многопоточном коде. проблема в том, что когда я выпускаю каждый из этих кадров, размер свободной памяти не меняется! Я использую qt 4.8 и ubuntu 12.04 Размер моего ноутбука - 8 ГБ, поэтому у меня нет недостатка в памяти.

каждый кадр составляет 1,8 МБ, поэтому общий размер составляет 600 * 1,8 МБ = 1080 МБ

перед запуском программы мой свободный объем памяти составляет 6,8 ГБ, но после запуска моего кода и разрешения его завершения я вижу, что размер свободной памяти составляет 5,9 ГБ, поэтому я вижу там огромную утечку памяти в программе. Я запустил свой код 1000 раз и никогда не видел сбоев в работе программы или сталкивался с любыми проблемами, поэтому код в порядке.

Мой код:

#include "im_loader.h"

IM_Loader::IM_Loader(QObject *parent) :
    QThread(parent)
{
}


void IM_Loader::run()
{
    QString PATH = "/home/parsa/QtProjects/MonoSD/";
     {
     for(float i = 0 ; i < 1 ; i++)
       {
         QString Folder_Address = PATH + QString::number((int)i)+"/";
         QDir Mydir(Folder_Address);
         Mydir.setFilter(QDir::Files);
         QFileInfoList Vehicles_list = Mydir.entryInfoList();
         qDebug()<<"Address is: "<<Folder_Address<<"\n";
         qDebug()<<"Number of images are: "<<Vehicles_list.size()<<"\n";
         static int overall_counter = 0; //12451
         for(int j = 0 ; j < 600 ; j++)
           {
             if(!Stop_Disp)
             {
                QString address = Folder_Address + QString::number(overall_counter++) +".jpg";
                cv::Mat image = cv::imread(address.toUtf8().constData(),0);
                if(!image.data)
                {
                    qDebug()<<"Image Data is failed ... \n";
                    continue;
                }
                if(j%100==0)
                qDebug()<<"Folder "<<i<<" Image No. "<<j<<" is processed, Overall counter is: "<<overall_counter<<"\n";
                cv::Mat Dataaa;
                image.copyTo(Dataaa);
                QMutexLocker Locker(&Global_Mutex);
                PD_Classifier_VEC.push_back(Dataaa);
                Locker.unlock();
                }
            }
        }
     }
    qDebug("Im loader is exited now ...");
}

im_loader.h

#ifndef IM_LOADER_H
#define IM_LOADER_H


#include "Definitions.h"

class IM_Loader : public QThread
{
    Q_OBJECT
public:
    explicit IM_Loader(QObject *parent = 0);
    void run();
    bool Stop_Disp;
signals:

public slots:

};

#endif // IM_LOADER_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
QTimer *Mytimer;
QMutex Global_Mutex;
IM_Loader IML;
std::vector<cv::Mat> PD_Classifier_VEC;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    IML.start();
    Mytimer = new QTimer(this);
    Mytimer->singleShot(20000,this,SLOT(Clear_Vec()));
}

void MainWindow::Clear_Vec()
{
    qDebug()<<"PD_Classifier_VEC.SIZE IS: "<<PD_Classifier_VEC.size();
    for(int i = 0 ; i < PD_Classifier_VEC.size() ; i++)
    {
        QMutexLocker Locker(&Global_Mutex);
        PD_Classifier_VEC.erase(PD_Classifier_VEC.begin() + i);
        Locker.unlock();
        i--;
    }
   Mytimer->singleShot(10000,this,SLOT(Clear_Vec()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "Definitions.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void Delay(int Milisecond_Delay);
public slots:
    void Clear_Vec();
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

Definitions.h

#ifndef DEFINITIONS_H
#define DEFINITIONS_H
#include <QMainWindow>
#include <QThread>
#include <QTimer>
#include <QDebug>
#include <QDir>
#include <QMutex>
#include <QMutexLocker>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "im_loader.h"

extern std::vector<cv::Mat> PD_Classifier_VEC;
extern QMutex Global_Mutex;
#endif // DEFINITIONS_H

В некоторых статьях я читал, что версия opencv C++ поддерживает управление памятью, поэтому нам не нужно беспокоиться о утечке памяти.

я что-то упустил? Я тоже читал эти вопросы, но никто из них не работал для меня это и это

Только одно сообщение меня забавляло, и я подумал, есть ли у меня эта проблема в моем коде, но я не мог понять. это ссылка

При необходимости я предоставлю что-нибудь еще.

Редакция:

очень интересно, что если я добавлю функцию Delay в класс imageloader сразу после прочтения каждого кадра, количество утечек памяти уменьшится !!!

Мой новый im_loader.cpp

void IM_Loader::Delay(int Milisecond_Delay)
{
    double OneSecond = cv::getTickFrequency();
    int Milisecond = OneSecond/4000;

   for(double t1= 0 ; t1 < Milisecond_Delay ; t1++)
          for(double t2= 0 ; t2 < Milisecond; t2++);
}
void IM_Loader::run()
{
    QString PATH = "/home/parsa/QtProjects/FINAL_VLPR/LowSpeed/";//Dataset_PATH;
     //while(1)
     {
     for(float i = 0 ; i < 1 ; i++)
       {
         QString Folder_Address = PATH + QString::number((int)i)+"/";
         QDir Mydir(Folder_Address);
         Mydir.setFilter(QDir::Files);
         QFileInfoList Vehicles_list = Mydir.entryInfoList();
         qDebug()<<"Address is: "<<Folder_Address<<"\n";
         qDebug()<<"Number of images are: "<<Vehicles_list.size()<<"\n";
         static int overall_counter = 0; //12451
         for(int j = 0 ; j < 300 ; j++)
           {
             if(!Stop_Disp)
             {
                QString address = Folder_Address + QString::number(overall_counter++) +".jpg";
                cv::Mat image = cv::imread(address.toUtf8().constData(),0);
                Delay(100);
                if(!image.data)
                {
                    qDebug()<<"Image Data is failed ... \n";
                    continue;
                }
                if(j%100==0)
                qDebug()<<"Folder "<<i<<" Image No. "<<j<<" is processed, Overall counter is: "<<overall_counter<<"\n";
                cv::Mat Dataaa;
                image.copyTo(Dataaa);
                QMutexLocker Locker(&Global_Mutex);
                PD_Classifier_VEC.push_back(Dataaa);
                Locker.unlock();
                }
            }
        }
     }
    qDebug("Im loader is exited now ...");
}

добавление задержки 100 мс уменьшило утечку памяти до 100 мегабайт вместо 1 гигабайта !!!

Теги:
opencv
qt
memory-leaks
ubuntu-12.04

1 ответ

0
Лучший ответ

Наконец, я узнал, что вызвало эту утечку памяти... как вы можете видеть в классе im_loader и в частности функции run() У меня есть этот блок кода:

 cv::Mat Dataaa;
 image.copyTo(Dataaa);
 QMutexLocker Locker(&Global_Mutex);
 PD_Classifier_VEC.push_back(Dataaa);
 Locker.unlock();

Поскольку OpenCV использует процедуру подсчета ссылок для объекта cv :: Mat, входное изображение копируется в переменную Dataa, а затем в PD_Classifier. PD_Classifier удаляется, но Dataa no! поэтому, когда я удалил эту строку и изменил код на эту проблему, проблема была решена:

  QMutexLocker Locker(&Global_Mutex);
  PD_Classifier_VEC.push_back(image);
  Locker.unlock();

Я думал, что поскольку Dataa - это локальная переменная, она будет удалена после выхода из функции run(), но кажется, что, хотя она удаляется после выхода из функции, ее данные остаются в памяти.

  • 0
    В следующий раз используйте подходящие инструменты для анализа памяти, такие как Valgrind, который, кстати, интегрирован в Qt Creator, хотя я не уверен, насколько хорошо, поэтому было бы неплохо полагаться и на консоль. Он также имеет возможность анализировать параллельные программы, что в вашем случае. Я использовал это в Eclipse и в консоли.
  • 0
    @rbaleksandar Я тестировал свой код, используя valgrind, но не получил от него никакого результата. Valgrind не смог обнаружить, что происходит, и я думаю, что это из-за алгоритма подсчета ссылок OpenCV.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню