Утечка памяти в градиенте собственных конъюгатов?
Я провел последний день в поисках утечки памяти в моем коде. Для каждого кадра в цикле я вижу в диспетчере задач, что потеряно около 200 Мб памяти. В конце концов программа конечно вылетает.
Псевдокод выглядит так:
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 Мб теряются для каждого кадра.
В 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
,
РЕДАКТИРОВАТЬ: Как указал Ави Гинзбург, я использовал бета-версию Eigen. При обновлении до 3.3.2 он работает без утечек памяти.