From ecaa14456e3f5916e6ef2b08095d61f61f19eeae Mon Sep 17 00:00:00 2001 From: Weiqun Zhang Date: Wed, 11 Oct 2023 16:22:23 -0700 Subject: [PATCH] Fix a memory "leak" in VisMF's persistent streams (#3592) ## Summary VisMF uses a std::map to keep track of the streams it opens. Each PersistentIFStream object also has a vector used as IO buffer. When a stream is closed, we need to free to memory used by the buffer. The issue was it used std::vector::clear(), which only changes size() without reducing capacity() at all. So the memory was never freed. The issue is now fixed by std::vector::swap. ## Additional background Thank Simon Guichandut (@simonguichandut) for reporting this! Thank Eric Johnson (@yut23) for pinning down the location of the leak with the help of the Massif heap profiler! ## Checklist The proposed changes: - [x] fix a bug or incorrect behavior in AMReX - [ ] add new capabilities to AMReX - [ ] changes answers in the test suite to more than roundoff level - [ ] are likely to significantly affect the results of downstream AMReX users - [ ] include documentation in the code and/or rst files, if appropriate --- Src/Base/AMReX_VisMF.cpp | 2 +- Src/Base/AMReX_VisMFBuffer.H | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Src/Base/AMReX_VisMF.cpp b/Src/Base/AMReX_VisMF.cpp index 52efe827460..912be0b9b99 100644 --- a/Src/Base/AMReX_VisMF.cpp +++ b/Src/Base/AMReX_VisMF.cpp @@ -2202,7 +2202,7 @@ void VisMF::CloseStream(const std::string &fileName, bool forceClose) pifs.pstr = nullptr; pifs.isOpen = false; } - pifs.ioBuffer.clear(); + VisMFBuffer::ClearBuffer(pifs.ioBuffer); } diff --git a/Src/Base/AMReX_VisMFBuffer.H b/Src/Base/AMReX_VisMFBuffer.H index 843e5713f34..f095dbbebf2 100644 --- a/Src/Base/AMReX_VisMFBuffer.H +++ b/Src/Base/AMReX_VisMFBuffer.H @@ -29,6 +29,10 @@ public: ioBufferSize = iobuffersize; } + static void ClearBuffer (IO_Buffer& buf) { + IO_Buffer().swap(buf); + } + protected: static AMREX_EXPORT Long ioBufferSize; //!< ---- the settable buffer size