diff options
author | Björn-Egil Dahlberg <[email protected]> | 2012-12-07 17:41:42 +0100 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2012-12-14 15:13:00 +0100 |
commit | 53cabc7eda09dbe38df565cbf87d2f1ab3cd68e4 (patch) | |
tree | 7153a7ec7e06b5773e10e228463fd6f535f9a88d /erts | |
parent | f75be3a35f20504161a4e11488a3d6ce96552c52 (diff) | |
download | otp-53cabc7eda09dbe38df565cbf87d2f1ab3cd68e4.tar.gz otp-53cabc7eda09dbe38df565cbf87d2f1ab3cd68e4.tar.bz2 otp-53cabc7eda09dbe38df565cbf87d2f1ab3cd68e4.zip |
erts: Reduce max heap sizes
Reduces max heap sizes to max addressable memory space. In reality this could be
even less since we need at least twice as much adressable memory to do a garbage
collection.
The rest of the system also uses memory thus further constraining heap memory
space and in the 64 bit case we really only have 48 bits mappable memory.
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/erl_gc.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index cf06cedf7f..2917f6526a 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -129,7 +129,7 @@ static void disallow_heap_frag_ref(Process* p, Eterm* n_htop, Eterm* objv, int n #if defined(ARCH_64) && !HALFWORD_HEAP # define MAX_HEAP_SIZES 154 #else -# define MAX_HEAP_SIZES 55 +# define MAX_HEAP_SIZES 59 #endif static Sint heap_sizes[MAX_HEAP_SIZES]; /* Suitable heap sizes. */ @@ -144,6 +144,7 @@ void erts_init_gc(void) { int i = 0; + Sint max_heap_size = 0; ASSERT(offsetof(ProcBin,thing_word) == offsetof(struct erl_off_heap_header,thing_word)); ASSERT(offsetof(ProcBin,thing_word) == offsetof(ErlFunThing,thing_word)); @@ -179,11 +180,19 @@ erts_init_gc(void) heap_sizes[i] = heap_sizes[i-1] + heap_sizes[i-2] + 1; } + + /* for 32 bit we want max_heap_size to be MAX(32bit) / 4 [words] (and halfword) + * for 64 bit we want max_heap_size to be MAX(52bit) / 8 [words] + */ + + max_heap_size = sizeof(Eterm) < 8 ? (Sint)((~(Uint)0)/(sizeof(Eterm))) : + (Sint)(((Uint64)1 << 53)/sizeof(Eterm)); + /* Growth stage 2 - 20% growth */ /* At 1.3 mega words heap, we start to slow down. */ for (i = 23; i < ALENGTH(heap_sizes); i++) { heap_sizes[i] = heap_sizes[i-1] + heap_sizes[i-1]/5; - if (heap_sizes[i] < 0) { + if ((heap_sizes[i] < 0) || heap_sizes[i] > max_heap_size) { /* Size turned negative. Discard this last size. */ i--; break; @@ -860,14 +869,12 @@ minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl) } } - if (wanted < MIN_HEAP_SIZE(p)) { - wanted = MIN_HEAP_SIZE(p); - } else { - wanted = next_heap_size(p, wanted, 0); - } + wanted = wanted < MIN_HEAP_SIZE(p) ? MIN_HEAP_SIZE(p) + : next_heap_size(p, wanted, 0); if (wanted < HEAP_SIZE(p)) { shrink_new_heap(p, wanted, objv, nobj); } + ASSERT(HEAP_SIZE(p) == next_heap_size(p, HEAP_SIZE(p), 0)); return 1; /* We are done. */ } @@ -1426,11 +1433,10 @@ adjust_after_fullsweep(Process *p, Uint size_before, int need, Eterm *objv, int I think this is better as fullsweep is used mainly on small memory systems, but I could be wrong... */ wanted = 2 * need_after; - if (wanted < p->min_heap_size) { - sz = p->min_heap_size; - } else { - sz = next_heap_size(p, wanted, 0); - } + + sz = wanted < p->min_heap_size ? p->min_heap_size + : next_heap_size(p, wanted, 0); + if (sz < HEAP_SIZE(p)) { shrink_new_heap(p, sz, objv, nobj); } |