我已经尝试调试了一个月,确定这是我糟糕的编程习惯,但我认为这可能是一个错误,所以我在报告之前先在这里询问。
考虑以下代码:
#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, 0, 0, 100,100, area);
percepUnitsForeground.push_back(thisUnit); // Append to percepUnits
}
}
/* The following does not:
findContours(foreground, contours, CV_RETR_EXTERNAL, 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, contourImage, 0, 0, 100,100, 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() 函数应该退出,为每一帧释放所有使用的内存。内存使用量应该随着时间的推移保持不变,因为我们只在函数退出后检查内存使用量。似乎有些东西我无法弄清楚。
如果我只运行 findContours() 部分而没有 percepUnit() 构造函数,则内存使用量是不变的,正如我所料。如果我只运行不带 findContours() 的 percepUnit() 构造函数,则内存使用量是恒定的。仅当我同时使用两者时,内存使用量才会增加。请参阅上面的 segmentForeground() 中的注释代码。
我已经在我的两台机器(AMD64、linux)上确认了这个问题,并运行了 opencv 2.4.6.1 和 2.4.5。
编辑1
上面的代码已更改为包含以下建议,但问题仍然存在。
这是内存增加的样子:
(来源:ekran.org)
红线是调用 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, 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, int, int, int, int) (leakTest.cpp:43)
==2055== by 0x401E0E: segmentForeground(std::list<percepUnit*, std::allocator<percepUnit*> >&, cv::Mat&, 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*, int) (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055== by 0x4ECE378: cv::_OutputArray::create(int, int, 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 0x402897: percepUnit::percepUnit(cv::Mat&, cv::Mat&, int, int, int, int, int) (leakTest.cpp:42)
==2055== by 0x401E0E: segmentForeground(std::list<percepUnit*, std::allocator<percepUnit*> >&, cv::Mat&, 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, int const*, int) (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055== by 0x4ECE378: cv::_OutputArray::create(int, int, 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, int, int, int, int) (leakTest.cpp:43)
==2055== by 0x401E0E: segmentForeground(std::list<percepUnit*, std::allocator<percepUnit*> >&, cv::Mat&, 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, int const*, int) (in /usr/local/lib/libopencv_core.so.2.4.5)
==2055== by 0x4ECE378: cv::_OutputArray::create(int, int, 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 0x402897: percepUnit::percepUnit(cv::Mat&, cv::Mat&, int, int, int, int, int) (leakTest.cpp:42)
==2055== by 0x401E0E: segmentForeground(std::list<percepUnit*, std::allocator<percepUnit*> >&, cv::Mat&, 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*, std::allocator<percepUnit*> >&, cv::Mat&, 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,849,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)
所以基本上这似乎告诉我们在执行 clone() 的 percepUnit 构造函数中可能存在问题。在没有 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, 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 = percepUnit(frame, contourImage, 0, 0, 100,100, area);
percepUnitsForeground.push_back(thisUnit); // Append to percepUnits
}
}
/* The following does not:
findContours(foreground, contours, CV_RETR_EXTERNAL, 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, contourImage, 0, 0, 100,100, 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
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;
}
这是相应的 valgrind 输出:
==3562== Memcheck, a memory error detector
==3562== Copyright (C) 2002-2011, and GNU GPL'd, 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, 29,269,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 中运行此测试。)
(来源:ekran.org)
对于相同的代码,这里的地块输出:http ://www.ekran.org/tmp/massif.print.leak 未调用 findContours() 的非泄漏情况的地块输出,只有 percepUnit 构造函数:http ://www.ekran.org/tmp/massif.print.noLeak
编辑3
在跨线程(http://answers.opencv.org/question/19172/bug-increasing-memory-usage-per-iteration-when/)中建议我阅读 proc 而不是使用 rusage 方法,并且看看这个,内存并没有稳步增加:(!)
(来源:ekran.org)
这确实与地块输出相似!!所以我想我需要重做所有的单元测试。有人有理由我不应该在这里放弃并考虑这个问题吗?