1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Call malloc_trim() regularly to improve deallocation behavior (#14707)

This commit is contained in:
sfan5 2024-06-07 16:57:30 +02:00 committed by GitHub
parent 08485f6781
commit 71893807b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 99 additions and 4 deletions

View file

@ -63,7 +63,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <FindDirectory.h>
#endif
#include "config.h"
#if HAVE_MALLOC_TRIM
// glibc-only pretty much
#include <malloc.h>
#endif
#include "debug.h"
#include "filesys.h"
#include "log.h"
@ -72,6 +76,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <cstdarg>
#include <cstdio>
#include <signal.h>
#include <atomic>
#if !defined(SERVER) && defined(_WIN32)
// On Windows export some driver-specific variables to encourage Minetest to be
@ -903,4 +908,37 @@ double perf_freq = get_perf_freq();
#endif
#if HAVE_MALLOC_TRIM
/*
* On Linux/glibc we found that after deallocating bigger chunks of data (esp. MapBlocks)
* the memory would not be given back to the OS and would stay at peak usage.
* This appears to be a combination of unfortunate allocation order/fragmentation
* and the fact that glibc does not call madvise(MADV_DONTNEED) on its own.
* Some other allocators were also affected, jemalloc and musl libc were not.
* read more: <https://forum.minetest.net/viewtopic.php?t=30509>
*
* As a workaround we track freed memory coarsely and call malloc_trim() once a
* certain amount is reached.
*/
static std::atomic<size_t> memory_freed;
constexpr size_t MEMORY_TRIM_THRESHOLD = 128 * 1024 * 1024;
void TrackFreedMemory(size_t amount)
{
constexpr auto MO = std::memory_order_relaxed;
memory_freed.fetch_add(amount, MO);
if (memory_freed.load(MO) >= MEMORY_TRIM_THRESHOLD) {
// Synchronize call
if (memory_freed.exchange(0, MO) < MEMORY_TRIM_THRESHOLD)
return;
// Leave some headroom for future allocations
malloc_trim(1 * 1024 * 1024);
}
}
#endif
} //namespace porting