I am attempting to use the ROOT::Fit::Fitter class in combination with the GSLMultiFit minimizer and am running into a memory leak which seems to be inherent to the minimizer (as best as I can tell). I have been looking for ways around this issue without much success (I do not wish to change minimizers as this is threadsafe and provides both accurate and fast results) so any insight would be greatly appreciated. I am running Root 6.22.02 and please find a code snippet and valgrind report below:
Code snippet: //This code snippet is taken from a function which is called within a loop over many iterations.
ROOT::Math::WrappedMultiTF1 fitFunction(*f_fit, 3 ); //f_fit is a TF1
ROOT::Fit::BinData data(31,1);
ROOT::Fit::FillData(data,h_data); //h_data is a histogram of data filled earlier
ROOT::Fit::Chi2Function *EPChi2 = new ROOT::Fit::Chi2Function(data, fitFunction);
ROOT::Fit::Fitter fitter;
fitter.Config().MinimizerOptions().SetMinimizerType(“GSLMultiFit”);
fitter.Config().SetParamsSettings(3,params); //params is set up and is an array of 3 doubles
fitter.FitFCN(*EPChi2,0,data.Size(),true);
When running this over many iterations i notice a significant memory leak, and when checking with valgrind I can trace it back to:
==25373== 252,320 (116,544 direct, 135,776 indirect) bytes in 1,214 blocks are definitely lost in loss record 22,404 of 22,439
==25373== at 0x4C2AE3B: operator new(unsigned long) (vg_replace_malloc.c:422)
==25373== by 0x2068B2BA: ROOT::Fit::Chi2FCN<ROOT::Math::IBaseFunctionMultiDimTempl, ROOT::Math::IParametricFunctionMultiDimTempl >::Clone() const (Chi2FCN.h:112)
==25373== by 0x20656C89: ROOT::Math::BasicMinimizer::SetFunction(ROOT::Math::IBaseFunctionMultiDimTempl const&) (BasicMinimizer.cxx:243)
==25373== by 0x3381C845: ROOT::Math::GSLNLSMinimizer::SetFunction(ROOT::Math::IBaseFunctionMultiDimTempl const&) (GSLNLSMinimizer.cxx:174)
==25373== by 0x206841C4: ROOT::Fit::Fitter::DoInitMinimizer() (Fitter.cxx:857)
==25373== by 0x20684DAE: ROOT::Fit::Fitter::FitFCN() (Fitter.cxx:338)
It appears to me that it internally it is cloning the fit function but then not deleting the clone when finished. I have not been able to find a way to access and delete this clone or avoid this effect as it appears to happen at the time of fitting, though perhaps my interpretation is incorrect.