我花了最后一天在代码中查找内存泄漏。对于我的循环中的每个帧,我可以在任务管理器中看到大约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
之间。使用ConjugateGradient
以4.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.04
和g++ 5.4.0
。