加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – Bug?使用findContours()时增加每次迭代的内存使用量

发布时间:2020-12-16 09:47:00 所属栏目:百科 来源:网络整理
导读:我一直试图调试这个一个月,确定这是我糟糕的编程习惯,但我认为它可能是一个错误,所以我在这里先问我报告之前. 请考虑以下代码: #include sys/resource.h // memory management.#include stdio.h#include iostream#include iomanip#include "opencv2/highgui
我一直试图调试这个一个月,确定这是我糟糕的编程习惯,但我认为它可能是一个错误,所以我在这里先问我报告之前.

请考虑以下代码:

#include <sys/resource.h> // memory management.
#include <stdio.h>
#include <iostream>
#include <iomanip>

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/background_segm.hpp"

using namespace std;
using namespace cv;

// Load frame from disk.
void readFrame(int frameNum,Mat &frame) {
    // Construct filenames
    Mat image;
    stringstream number,filename;

    number << setw(7) << setfill('0') << frameNum; // expecting over 1e10 images over the installation period.
    filename << "../images/store-" << number.str() << ".jpg"; // assumes jpegs!//
    cout << "Loading filename: " << filename.str() << endl;

    image = imread( filename.str() );

    if (image.empty() or !image.data) {
        cout << "Input image empty:n";
    }

    frame = image.clone();
}

// Class to hold the perceptual chunks.
class percepUnit {

    public:
        cv::Mat image; // percept itself
        cv::Mat mask; // alpha channel

        // constructor method
        percepUnit(cv::Mat &ROI,cv::Mat &alpha,int ix,int iy,int iw,int ih,int area)  {
            image = ROI.clone();
            mask = alpha.clone();
        }
};

// Segment foreground from background
void segmentForeground(list<percepUnit*> &percepUnitsForeground,Mat &foreground,Mat &frame) {
    Mat contourImage = Mat(foreground.rows,foreground.cols,CV_8UC1,Scalar::all(0));
    vector<vector<Point>> contours;
    int area;

    // The following causes strange spikes in memory usage:
    // find contours
    findContours(foreground,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);

    for (int idx = 0; idx < contours.size(); idx++) {

        area = contourArea(contours[idx]);

        if (area > 100) {

            percepUnit *thisUnit = new percepUnit(frame,contourImage,100,area);
            percepUnitsForeground.push_back(thisUnit); // Append to percepUnits
        }
    }

    /* The following does not:
    findContours(foreground,CV_CHAIN_APPROX_SIMPLE);

    for (int idx = 0; idx < contours.size(); idx++) {
        area = contourArea(contours[idx]);
    }*/

    /* Neither does this:
    for (int idx = 0; idx < 10; idx++) {
        percepUnit *thisUnit = new percepUnit(frame,area);
        percepUnitsForeground.push_back(thisUnit); // Append to percepUnits
    }*/
}

int main(int argc,const char** argv)
{
    int frameCount = 78298; 
    Mat frame,foreground;
    BackgroundSubtractorMOG2 MOG2model;
    list<percepUnit*> scratchPercepUnitsForeground;

    // add rusage stuff
    struct rusage usage; // memory usage.

    for(int i=0; i<= 75; i++)
    {
        // run full segmenter here.  (background disabled)

        readFrame(frameCount,frame); // was frame = readFrame();

        // Only process if this frame actually loaded (non empty)
        if ( not frame.empty() ) {

            MOG2model(frame,foreground); // Update MOG2 model,downscale?

            // before we segment again clear scratch
            // TODO how to delete the actual memory allocated? Run delete on everything?
            for (list<percepUnit*>::iterator percepIter = scratchPercepUnitsForeground.begin(); 
                 percepIter != scratchPercepUnitsForeground.end();
                 percepIter++) {

                delete *percepIter; // delete what we point to.
                //percepIter = scratchPercepUnitsForeground.erase(percepIter); // remove the pointer itself,and update the iterator.
            }
            // Added with EDIT1
            scratchPercepUnitsForeground.clear();

            // Segment the foreground regions and generate boolImage to extract from background.
            segmentForeground(scratchPercepUnitsForeground,foreground,frame);

        }

        frameCount++;

        getrusage(RUSAGE_SELF,&usage);
        cout << "DEBUG leakTest_bug_report " << i << " " << usage.ru_maxrss/1024.0 << endl;
    }

    return 0;
}

如果您使用此处可用的图像(http://www.ekran.org/tmp/images.tar.gz),您会发现程序的内存使用量增加,并且它似乎随着前景轮廓的数量而增加.由于我正在清除每个帧的存储空间(scratchPercepUnitsForeground),我不明白为什么应该增加内存使用量. segmentForeground()函数应退出,为每个帧释放所有已用内存.由于我们仅在函数退出后检查内存使用情况,因此内存使用量应该随时间保持不变.似乎有些东西遗留下来,我无法弄明白.

如果我在没有percepUnit()构造函数的情况下只运行findContours()部分,则内存使用量是不变的,正如我所期望的那样.如果我只运行不带findContours()的percepUnit()构造函数,则内存使用量是不变的.只有当我同时使用时才会增加内存使用量请参阅上面的segmentForeground()中的注释代码.

我已经在我的两台机器(AMD64,linux)和运行opencv 2.4.6.1和2.4.5上确认了这个问题.

EDIT1

上面的代码已更改为包含以下建议,但问题仍然存在.

这是内存增加的样子:

Memory Usage http://www.ekran.org/tmp/memory.png

红线是在调用findContours()和构造函数时看到的内存增加(与上面链接的测试图像相关).下面的稳定行是我们运行findContours()或构造函数的两种情况.

Valgrind输出

==2055== Memcheck,a memory error detector
==2055== Copyright (C) 2002-2011,and GNU GPL'd,by Julian Seward et al.
==2055== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==2055== Command: ./leakTest
==2055== 
==2055== 
==2055== HEAP SUMMARY:
==2055==     in use at exit: 217,751,704 bytes in 112 blocks
==2055==   total heap usage: 800,066 allocs,799,954 frees,29,269,767,865 bytes allocated
==2055== 
==2055== 568 bytes in 1 blocks are still reachable in loss record 1 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x63A720A: __fopen_internal (iofopen.c:76)
==2055==    by 0xA8BC050: libjpeg_general_init (in /usr/lib/x86_64-linux-gnu/libjpeg.so.8.0.2)
==2055==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==2055==    by 0x400F3DE: _dl_init (dl-init.c:52)
==2055==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==2055== 
==2055== 2,072 bytes in 1 blocks are still reachable in loss record 2 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x1495F675: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x1495E4AE: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x14950888: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x149253B8: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==2055==    by 0x400F3DE: _dl_init (dl-init.c:52)
==2055==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==2055== 
==2055== 2,072 bytes in 1 blocks are still reachable in loss record 3 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x1495F675: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x1495E0EF: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x14950890: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x149253B8: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==2055==    by 0x400F3DE: _dl_init (dl-init.c:52)
==2055==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==2055== 
==2055== 2,072 bytes in 1 blocks are still reachable in loss record 4 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x1495F675: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x14971A6F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x14950898: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x149253B8: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==2055==    by 0x400F3DE: _dl_init (dl-init.c:52)
==2055==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==2055== 
==2055== 2,072 bytes in 1 blocks are still reachable in loss record 5 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x1495F675: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x1499024F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x149508A0: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x149253B8: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==2055==    by 0x400F3DE: _dl_init (dl-init.c:52)
==2055==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==2055== 
==2055== 2,072 bytes in 1 blocks are still reachable in loss record 6 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x1495F675: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x149610EF: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x149253B8: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==2055==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==2055==    by 0x400F3DE: _dl_init (dl-init.c:52)
==2055==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==2055== 
==2055== 4,096 bytes in 1 blocks are still reachable in loss record 7 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0xA8BC067: libjpeg_general_init (in /usr/lib/x86_64-linux-gnu/libjpeg.so.8.0.2)
==2055==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==2055==    by 0x400F3DE: _dl_init (dl-init.c:52)
==2055==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==2055== 
==2055== 1,555,228 bytes in 1 blocks are possibly lost in loss record 8 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x4E87A90: cv::fastMalloc(unsigned long) (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055==    by 0x4ECDBF1: cv::Mat::create(int,int const*,int) (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055==    by 0x4ECE378: cv::_OutputArray::create(int,int,bool,int) const (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055==    by 0x4F52F7D: cv::Mat::copyTo(cv::_OutputArray const&) const (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055==    by 0x40253C: cv::Mat::clone() const (mat.hpp:335)
==2055==    by 0x4028D5: percepUnit::percepUnit(cv::Mat&,cv::Mat&,int) (leakTest.cpp:43)
==2055==    by 0x401E0E: segmentForeground(std::list<percepUnit*,std::allocator<percepUnit*> >&,cv::Mat&) (leakTest.cpp:63)
==2055==    by 0x40202D: main (leakTest.cpp:114)
==2055== 
==2055== 37,325,024 bytes in 8 blocks are possibly lost in loss record 9 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x4E87A90: cv::fastMalloc(unsigned long) (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055==    by 0x4ECDBF1: cv::Mat::create(int,int) const (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055==    by 0x4F52F7D: cv::Mat::copyTo(cv::_OutputArray const&) const (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055==    by 0x40253C: cv::Mat::clone() const (mat.hpp:335)
==2055==    by 0x402897: percepUnit::percepUnit(cv::Mat&,int) (leakTest.cpp:42)
==2055==    by 0x401E0E: segmentForeground(std::list<percepUnit*,cv::Mat&) (leakTest.cpp:63)
==2055==    by 0x40202D: main (leakTest.cpp:114)
==2055== 
==2055== 52,877,752 bytes in 34 blocks are indirectly lost in loss record 10 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x4E87A90: cv::fastMalloc(unsigned long) (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055==    by 0x4ECDBF1: cv::Mat::create(int,cv::Mat&) (leakTest.cpp:63)
==2055==    by 0x40202D: main (leakTest.cpp:114)
==2055== 
==2055== 125,971,956 bytes in 27 blocks are indirectly lost in loss record 11 of 12
==2055==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x4E87A90: cv::fastMalloc(unsigned long) (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055==    by 0x4ECDBF1: cv::Mat::create(int,cv::Mat&) (leakTest.cpp:63)
==2055==    by 0x40202D: main (leakTest.cpp:114)
==2055== 
==2055== 178,856,428 (6,720 direct,178,849,708 indirect) bytes in 35 blocks are definitely lost in loss record 12 of 12
==2055==    at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2055==    by 0x401DD3: segmentForeground(std::list<percepUnit*,cv::Mat&) (leakTest.cpp:63)
==2055==    by 0x40202D: main (leakTest.cpp:114)
==2055== 
==2055== LEAK SUMMARY:
==2055==    definitely lost: 6,720 bytes in 35 blocks
==2055==    indirectly lost: 178,708 bytes in 61 blocks
==2055==      possibly lost: 38,880,252 bytes in 9 blocks
==2055==    still reachable: 15,024 bytes in 7 blocks
==2055==         suppressed: 0 bytes in 0 blocks
==2055== 
==2055== For counts of detected and suppressed errors,rerun with: -v
==2055== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 2 from 2)

所以基本上这似乎告诉我们,percepUnit构造函数中可能存在clone()的问题.在没有findContours()的情况下运行构造函数显示没有内存增加(如上所述),其中包括使用“new”. jpeg阅读器也经过了单元测试,没有内存增加.因此,valgrind输出似乎没有任何帮助.

这应该是可重复的!在提供答案之前,请确保您可以重现它.

EDIT2(修改后的代码和valgrind输出,删除指针方法)

在这里,我将列表从指向实例列表的指针列表中更改.内存增加得到确认.

#include <sys/resource.h> // memory management.
#include <stdio.h>
#include <iostream>
#include <iomanip>

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/background_segm.hpp"

using namespace std;
using namespace cv;

// Load frame from disk.
void readFrame(int frameNum,int area)  {
            image = ROI.clone();
            mask = alpha.clone();
        }
};

// Segment foreground from background
void segmentForeground(list<percepUnit> &percepUnitsForeground,CV_CHAIN_APPROX_SIMPLE);

    for (int idx = 0; idx < contours.size(); idx++) {

        area = contourArea(contours[idx]);

        if (area > 100) {

            percepUnit thisUnit = percepUnit(frame,CV_CHAIN_APPROX_SIMPLE);

    for (int idx = 0; idx < contours.size(); idx++) {
        area = contourArea(contours[idx]);
    }*/

    /* Neither does this:
    for (int idx = 0; idx < 10; idx++) {
        percepUnit thisUnit = percepUnit(frame,foreground;
    BackgroundSubtractorMOG2 MOG2model;
    list<percepUnit> scratchPercepUnitsForeground;

    // add rusage stuff
    struct rusage usage; // memory usage.

    for(int i=0; i<= 75; i++)
    {
        // run full segmenter here.  (background disabled)

        readFrame(frameCount,downscale?

            // before we segment again clear scratch
            scratchPercepUnitsForeground.clear();

            // Segment the foreground regions and generate boolImage to extract from background.
            segmentForeground(scratchPercepUnitsForeground,&usage);
        cout << "DEBUG leakTest_bug_report " << i << " " << usage.ru_maxrss/1024.0 << endl;
    }

    return 0;
}

这是相应的valgrind输出:

==3562== Memcheck,a memory error detector
==3562== Copyright (C) 2002-2011,by Julian Seward et al.
==3562== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==3562== Command: ./leakTest
==3562== 
==3562== 
==3562== HEAP SUMMARY:
==3562==     in use at exit: 15,024 bytes in 7 blocks
==3562==   total heap usage: 795,556 allocs,795,549 frees,731,785 bytes allocated
==3562== 
==3562== 568 bytes in 1 blocks are still reachable in loss record 1 of 7
==3562==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3562==    by 0x63A720A: __fopen_internal (iofopen.c:76)
==3562==    by 0xA8BC050: libjpeg_general_init (in /usr/lib/x86_64-linux-gnu/libjpeg.so.8.0.2)
==3562==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==3562==    by 0x400F3DE: _dl_init (dl-init.c:52)
==3562==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==3562== 
==3562== 2,072 bytes in 1 blocks are still reachable in loss record 2 of 7
==3562==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3562==    by 0x1495F675: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x1495E4AE: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x14950888: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x149253B8: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==3562==    by 0x400F3DE: _dl_init (dl-init.c:52)
==3562==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==3562== 
==3562== 2,072 bytes in 1 blocks are still reachable in loss record 3 of 7
==3562==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3562==    by 0x1495F675: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x1495E0EF: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x14950890: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x149253B8: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==3562==    by 0x400F3DE: _dl_init (dl-init.c:52)
==3562==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==3562== 
==3562== 2,072 bytes in 1 blocks are still reachable in loss record 4 of 7
==3562==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3562==    by 0x1495F675: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x14971A6F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x14950898: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x149253B8: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==3562==    by 0x400F3DE: _dl_init (dl-init.c:52)
==3562==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==3562== 
==3562== 2,072 bytes in 1 blocks are still reachable in loss record 5 of 7
==3562==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3562==    by 0x1495F675: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x1499024F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x149508A0: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x149253B8: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==3562==    by 0x400F3DE: _dl_init (dl-init.c:52)
==3562==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==3562== 
==3562== 2,072 bytes in 1 blocks are still reachable in loss record 6 of 7
==3562==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3562==    by 0x1495F675: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x149610EF: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x149253B8: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.24.4)
==3562==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==3562==    by 0x400F3DE: _dl_init (dl-init.c:52)
==3562==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==3562== 
==3562== 4,096 bytes in 1 blocks are still reachable in loss record 7 of 7
==3562==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3562==    by 0xA8BC067: libjpeg_general_init (in /usr/lib/x86_64-linux-gnu/libjpeg.so.8.0.2)
==3562==    by 0x400F305: call_init.part.0 (dl-init.c:85)
==3562==    by 0x400F3DE: _dl_init (dl-init.c:52)
==3562==    by 0x40016E9: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==3562== 
==3562== LEAK SUMMARY:
==3562==    definitely lost: 0 bytes in 0 blocks
==3562==    indirectly lost: 0 bytes in 0 blocks
==3562==      possibly lost: 0 bytes in 0 blocks
==3562==    still reachable: 15,024 bytes in 7 blocks
==3562==         suppressed: 0 bytes in 0 blocks
==3562== 
==3562== For counts of detected and suppressed errors,rerun with: -v
==3562== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

然而,记忆仍然无法解释地增加:(之前情节的总体增长是由于在valgrind中运行此测试.)

memory usage http://www.ekran.org/tmp/memory2.png

对于相同的代码,这里是massif输出:http://www.ekran.org/tmp/massif.print.leak
没有调用findContours()的非泄漏情况的massif输出,只有percepUnit构造函数:http://www.ekran.org/tmp/massif.print.noLeak

EDIT3

在跨线程(http://answers.opencv.org/question/19172/bug-increasing-memory-usage-per-iteration-when/)中建议我读取proc而不是使用rusage方法,看看这个,内存不会稳定增加:(!)

memory usage http://www.ekran.org/tmp/memory_proc.png

这确实看起来类似于地块输出!!所以我想我需要重做所有的单元测试.任何人都有理由我不应该放弃这个问题来考虑问题吗?

解决方法

对我来说,你的图形分析与rusage单调增加的事实是可疑的.

对于rusage状态的文档:

The maximum resident set size used,in kilobytes. That is,the maximum number of kilobytes of physical memory that processes used simultaneously.

由于您可能只针对多个图像收集相同过程的统计信息,因此rusage报告所有图像的最大内存使用量的结论是有意义的.

实际上,使用不同的分析工具(OS X上的Instruments)会生成显示当前内存使用情况的图表:

这与使用proc的结果非常相似.我会得出结论,rusage不是你想要的分析工具.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读