特征共轭梯度中的内存泄漏?

时间:2017-02-14 10:33:45

标签: memory-leaks eigen eigen3

我花了最后一天在代码中查找内存泄漏。对于我的循环中的每个帧,我可以在任务管理器中看到大约200 Mb的内存丢失。最终程序当然崩溃了。

伪代码如下所示:

 for frame = 0:NBROFFRAMES
     cv::Mat = getImage(frame);
     cout<<"Before optimization"<<endl;
     getchar();
     optFunction.optimizeColor(img);
     cout<<"After optimization"<<endl;
     getchar();
     Do other things
 end

只需查看任务管理器即可显示optimizeColor每帧丢失约200 Mb。

optimizeColor我多次运行Eigens ConjugateGradient。当我更改为Cholesky Factorization, SimplicialLDLT时,整个序列的内存消耗在4.5-4.7 Gb之间。使用ConjugateGradient4.5 Gb开头,在10张图片之后,根据我的任务管理器使用的内存量为11.2 Gb

我还运行Valgrind,其中一条消息如下:

==22576== 110,430,720 bytes in 18 blocks are possibly lost in loss record 30,186 of 30,189
==22576==    at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22576==    by 0x913CCD: Eigen::internal::scoped_array<int>::scoped_array(long) (Memory.h:666)
==22576==    by 0x910329: Eigen::internal::CompressedStorage<float, int>::reallocate(long) (CompressedStorage.h:230)
==22576==    by 0x910695: Eigen::internal::CompressedStorage<float, int>::resize(long, double) (CompressedStorage.h:96)
==22576==    by 0x91CC41: Eigen::SparseMatrix<float, 0, int>& Eigen::SparseMatrix<float, 0, int>::operator=<Eigen::SparseMatrix<float, 1, int> >(Eigen::SparseMatrixBase<Eigen::SparseMatrix<float, 1, int> > const&) (SparseMatrix.h:1085)
==22576==    by 0x91A911: Eigen::SparseMatrix<float, 0, int>::SparseMatrix<Eigen::SparseMatrix<float, 1, int> >(Eigen::SparseMatrixBase<Eigen::SparseMatrix<float, 1, int> > const&) (SparseMatrix.h:674)
==22576==    by 0x91837C: void Eigen::Ref<Eigen::SparseMatrix<float, 0, int> const, 0, Eigen::OuterStride<-1> >::construct<Eigen::SparseMatrix<float, 1, int> >(Eigen::SparseMatrix<float, 1, int> const&, Eigen::internal::false_type) (SparseRef.h:217)
==22576==    by 0x91631C: Eigen::Ref<Eigen::SparseMatrix<float, 0, int> const, 0, Eigen::OuterStride<-1> >::Ref<Eigen::SparseMatrix<float, 1, int> >(Eigen::SparseMatrixBase<Eigen::SparseMatrix<float, 1, int> > const&) (SparseRef.h:184)
==22576==    by 0x913801: void Eigen::internal::generic_matrix_wrapper<Eigen::SparseMatrix<float, 0, int>, false>::grab<Eigen::SparseMatrix<float, 1, int> >(Eigen::EigenBase<Eigen::SparseMatrix<float, 1, int> > const&) (IterativeSolverBase.h:81)
==22576==    by 0x90FEFE: void Eigen::IterativeSolverBase<Eigen::ConjugateGradient<Eigen::SparseMatrix<float, 0, int>, 3, Eigen::DiagonalPreconditioner<float> > >::grab<Eigen::SparseMatrix<float, 1, int> >(Eigen::SparseMatrix<float, 1, int> const&) (IterativeSolverBase.h:375)
==22576==    by 0x90C03D: Eigen::ConjugateGradient<Eigen::SparseMatrix<float, 0, int>, 3, Eigen::DiagonalPreconditioner<float> >& Eigen::IterativeSolverBase<Eigen::ConjugateGradient<Eigen::SparseMatrix<float, 0, int>, 3, Eigen::DiagonalPreconditioner<float> > >::analyzePattern<Eigen::SparseMatrix<float, 1, int> >(Eigen::EigenBase<Eigen::SparseMatrix<float, 1, int> > const&) (IterativeSolverBase.h:199)
==22576==    by 0x9077F3: OptimizeAlbedo::optimize_rho(cv::Mat const&, std::vector<Eigen::Matrix<float, -1, 1, 0, -1, 1>, std::allocator<Eigen::Matrix<float, -1, 1, 0, -1, 1> > > const&, std::vector<Eigen::Matrix<int, 2, 1, 0, 2, 1>, std::allocator<Eigen::Matrix<int, 2, 1, 0, 2, 1> > > const&, Eigen::Matrix<float, -1, 1, 0, -1, 1> const&, float, float, Eigen::Matrix<float, -1, 1, 0, -1, 1> const&) (OptimizeAlbedo.cpp:586)

我做的唯一分配内存的是我在创建实例optFunction时定义某些矩阵的大小并为条目保留空间。那当然只做了一次,我已经多次检查过了。我看到的唯一解释是ConjugateGradient正在消耗内存。

以下是我调用ConjugateGradient的代码:

function optmize()
Eigen::ConjugateGradient<Eigen::SparseMatrix<float>, Eigen::Lower | Eigen::Upper> cg;
cg.setTolerance(0.001);
cg.setMaxIterations(200);
cg.analyzePattern(A_tot);
cg.factorize(A_tot);
Eigen::VectorXf opt = cg.solveWithGuess(b_tot, rho_current);
end

我希望当函数超出范围时清除cg,但似乎情况并非如此。

我认为我使用Eigen version: 3.2.92,这是Macros.h

#define EIGEN_WORLD_VERSION 3
#define EIGEN_MAJOR_VERSION 2
#define EIGEN_MINOR_VERSION 92

我正在使用Ubuntu 16.04g++ 5.4.0

编辑:正如Avi Ginsburg所指出的那样,我使用的是Eigen的beta版本。通过升级到3.3.2,它可以在没有内存泄漏的情况下工作。

0 个答案:

没有答案