From 538b7caab013e6ec78bed2b65a7c5d345f1c737e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 10 Feb 2011 14:31:04 +0000 Subject: [PATCH] * Don't allocate a big initial GC address space on machines with little RAM. Even if the memory isn't actually used, it can cause problems with the overcommit heuristics in the kernel. So use a VM space of 25% of RAM, up to 384 MB. --- configure.ac | 2 +- src/libexpr/eval.cc | 35 ++++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index b487a8fdaa..deb011d1c7 100644 --- a/configure.ac +++ b/configure.ac @@ -284,7 +284,7 @@ AC_CHECK_FUNCS([setresuid setreuid lchown]) # Nice to have, but not essential. -AC_CHECK_FUNCS([strsignal posix_fallocate nanosleep]) +AC_CHECK_FUNCS([strsignal posix_fallocate nanosleep sysconf]) # This is needed if ATerm or bzip2 are static libraries, diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index b95c9a6d17..949f45e787 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -7,6 +7,7 @@ #include "globals.hh" #include +#include #if HAVE_BOEHMGC @@ -155,17 +156,29 @@ EvalState::EvalState() #if HAVE_BOEHMGC static bool gcInitialised = true; if (gcInitialised) { - /* Set the initial heap size to something fairly big (384 MiB) - so that in most cases we don't need to garbage collect at - all. (Collection has a fairly significant overhead.) The - heap size can be overriden through libgc's - GC_INITIAL_HEAP_SIZE environment variable. We should - probably also provide a nix.conf setting for this. Note - that GC_expand_hp() causes a lot of virtual, but not - physical (resident) memory to be allocated. This might be - a problem on systems that don't overcommit. */ - if (!getenv("GC_INITIAL_HEAP_SIZE")) - GC_expand_hp(384 * 1024 * 1024); + /* Set the initial heap size to something fairly big (25% of + physical RAM, up to a maximum of 384 MiB) so that in most + cases we don't need to garbage collect at all. (Collection + has a fairly significant overhead.) The heap size can be + overriden through libgc's GC_INITIAL_HEAP_SIZE environment + variable. We should probably also provide a nix.conf + setting for this. Note that GC_expand_hp() causes a lot of + virtual, but not physical (resident) memory to be + allocated. This might be a problem on systems that don't + overcommit. */ + if (!getenv("GC_INITIAL_HEAP_SIZE")) { + size_t maxSize = 384 * 1024 * 1024; + size_t size = 32 * 1024 * 1024; +#if HAVE_SYSCONF && defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES) + long pageSize = sysconf(_SC_PAGESIZE); + long pages = sysconf (_SC_PHYS_PAGES); + if (pageSize != -1 && size != -1) + size = (pageSize * pages) / 4; // 25% of RAM + if (size > maxSize) size = maxSize; +#endif + debug(format("setting initial heap size to %1% bytes") % size); + GC_expand_hp(size); + } gcInitialised = true; } #endif