Question

J'ai écrit un programme C ++ très simple pour lire 600 images vidéo dans un code multi-threadé. Le problème est que lorsque je libère chacun de ces cadres, la taille de la mémoire gratuite ne change pas! J'utilise Qt 4.8 et Ubuntu 12.04 La taille de la mémoire de mon ordinateur portable est de 8 Go, donc je n'ai aucune pénurie de mémoire.

Chaque image est de 1,8 Mo, de sorte que la taille totale est de 600 * 1,8 MB= 1080 Mo

Avant d'exécuter le programme, ma taille de mémoire de mémoire est de 6,8 Go, mais après avoir exécuté mon code et le laisser finir, je vois que la taille de la mémoire gratuite est de 5,9 Go, donc je vois qu'il y a une énorme fuite de mémoire dans le programme. J'ai exécuté mon code 1000 fois et je n'ai jamais vu mon programme se bloque ni faire face à des problèmes afin que le code soit correct.

Mon code:

#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

définitions.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

J'ai lu dans certains articles que la version OpenCV C ++ prend en charge la gestion de la mémoire afin de ne pas avoir à vous inquiéter des fuites de mémoire.

Est-ce que je manque quelque chose ici? J'ai lu ces questions aussi mais aucun d'entre eux n'a travaillé pour moi Ce et Ceci

Juste un post amusé me est tellement et m'a fait penser si j'ai ce problème dans mon code mais je ne pouvais pas comprendre. C'est le lien

Je vais fournir autre chose si nécessaire.

édité:

Il est très intéressant que si j'ajoute une fonction de retard dans ma classe ImageLoaderer juste après avoir lu chaque image, la quantité de fuites de mémoire réduit !!!

mon nouveau 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 ...");
}

Ajout d'un délai de 100 ms Réduit la fuite de mémoire à seulement 100 méga octets au lieu de 1 gigaoctet !!!

Était-ce utile?

La solution

Enfin, j'ai découvert ce qui a provoqué cette fuite de mémoire ... Comme vous pouvez le voir dans la classe IM_Loader et spécifiquement exécuter (), j'ai ce bloc de code:

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

Depuis OpenCV, utilisez une procédure de comptage de référence pour CV :: Mat objet, l'image d'entrée est copiée dans la variable DATADA, puis dans PD_Classifiant.Pd_classificateur est supprimé mais dataa no!Donc, lorsque j'ai supprimé cette ligne et modifier le code dans ce problème, le problème a été résolu:

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

Je pensais que, étant donné que Dataa est une variable locale, elle sera supprimée après la sortie de la fonction RUN (), mais il semble que, bien qu'il soit supprimé après la sortie de la fonction, ses données restent sur la mémoire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top