From 334382f03121d28c0174fa33d9cb0c2f0a246ee8 Mon Sep 17 00:00:00 2001 From: Valentin Balaschenko <13349202+vlntb@users.noreply.github.com> Date: Thu, 13 Nov 2025 13:56:36 +0000 Subject: [PATCH] cleanup and notes --- include/xrpl/basics/MallocTrim.h | 48 ++++++++++++++++++++++++------- src/libxrpl/basics/MallocTrim.cpp | 3 +- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/include/xrpl/basics/MallocTrim.h b/include/xrpl/basics/MallocTrim.h index 5371171ce9..b518bafd19 100644 --- a/include/xrpl/basics/MallocTrim.h +++ b/include/xrpl/basics/MallocTrim.h @@ -8,6 +8,20 @@ namespace ripple { +// ----------------------------------------------------------------------------- +// Allocator interaction note: +// - This facility invokes glibc's malloc_trim(0) on Linux/glibc to request that +// ptmalloc return free heap pages to the OS. +// - If an alternative allocator (e.g. jemalloc or tcmalloc) is linked or +// preloaded (LD_PRELOAD), calling glibc's malloc_trim typically has no effect +// on the *active* heap. The call is harmless but may not reclaim memory +// because those allocators manage their own arenas. +// - Only glibc sbrk/arena space is eligible for trimming; large mmap-backed +// allocations are usually returned to the OS on free regardless of trimming. +// - Call at known reclamation points (e.g., after cache sweeps / online delete) +// and consider rate limiting to avoid churn. +// ----------------------------------------------------------------------------- + struct MallocTrimReport { bool supported{false}; @@ -15,24 +29,38 @@ struct MallocTrimReport long rssBeforeKB{-1}; long rssAfterKB{-1}; - long - deltaKB() const + [[nodiscard]] long + deltaKB() const noexcept { + if (rssBeforeKB < 0 || rssAfterKB < 0) + return 0; return rssAfterKB - rssBeforeKB; } }; -/** Attempt to return freed memory to the operating system. +/** + * @brief Attempt to return freed memory to the operating system. * - * This function is only effective on Linux with glibc. On other platforms, - * it returns a report indicating the operation is unsupported. + * On Linux with glibc malloc, this issues ::malloc_trim(0), which may release + * free space from ptmalloc arenas back to the kernel. On other platforms, or if + * a different allocator is in use, this function is a no-op and the report will + * indicate that trimming is unsupported or had no effect. * - * @param tag Optional identifier for logging/debugging purposes - * @param journal Journal for logging diagnostic information - * @return Report containing before/after memory metrics + * @param tag Optional identifier for logging/debugging purposes. + * @param journal Journal for diagnostic logging. + * @return Report containing before/after metrics and the trim result. * - * @note This is intended for use after cache sweeps or other operations - * that free significant amounts of memory. + * @note If an alternative allocator (jemalloc/tcmalloc) is linked or preloaded, + * calling glibc's malloc_trim may have no effect on the active heap. The + * call is harmless but typically does not reclaim memory under those + * allocators. + * + * @note Only memory served from glibc's sbrk/arena heaps is eligible for trim. + * Large allocations satisfied via mmap are usually returned on free + * independently of trimming. + * + * @note Intended for use after operations that free significant memory (e.g., + * cache sweeps, ledger cleanup, online delete). Consider rate limiting. */ MallocTrimReport mallocTrim(std::optional const& tag, beast::Journal journal); diff --git a/src/libxrpl/basics/MallocTrim.cpp b/src/libxrpl/basics/MallocTrim.cpp index 2c154503c2..c7e547f123 100644 --- a/src/libxrpl/basics/MallocTrim.cpp +++ b/src/libxrpl/basics/MallocTrim.cpp @@ -51,7 +51,6 @@ mallocTrim( #if !(defined(__GLIBC__) && BOOST_OS_LINUX) JLOG(journal.debug()) << "malloc_trim not supported on this platform"; - return report; #else report.supported = true; @@ -89,9 +88,9 @@ mallocTrim( { report.trimResult = ::malloc_trim(0); } +#endif return report; -#endif } } // namespace ripple