Утечка памяти в градиенте собственных конъюгатов?

Я провел последний день в поисках утечки памяти в моем коде. Для каждого кадра в цикле я вижу в диспетчере задач, что потеряно около 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я бегу EigensConjugateGradient несколько раз. Когда я изменился на 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 он работает без утечек памяти.

0 ответов

Другие вопросы по тегам