aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2011-02-10 14:31:04 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2011-02-10 14:31:04 +0000
commit538b7caab013e6ec78bed2b65a7c5d345f1c737e (patch)
tree8eeabda8f593d6adcfe815c807ab2a07cf4ba3a1
parent5a6b0398026a8a24b206a4b4d43894f9c683792c (diff)
* 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.
-rw-r--r--configure.ac2
-rw-r--r--src/libexpr/eval.cc35
2 files changed, 25 insertions, 12 deletions
diff --git a/configure.ac b/configure.ac
index b487a8fda..deb011d1c 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 b95c9a6d1..949f45e78 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -7,6 +7,7 @@
#include "globals.hh"
#include <cstring>
+#include <unistd.h>
#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