From c6185c8034444aa6b08941280607f4eadb52d571 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 4 Mar 2013 16:02:59 -0700 Subject: [PATCH] remove "low memory" heuristic from heap code The original goal was to minimize memory usage by garbage collecting more frequently and more comprehensively as we got closer to the heap limit. In practice, though, this just slowed the VM to a crawl as memory pressure increased. If an app really wants to use a lot of memory, the VM shouldn't penalize it aside from throwing an OutOfMemoryError if it exceeds the limit. --- src/heap/heap.cpp | 51 ++++++----------------------------------------- 1 file changed, 6 insertions(+), 45 deletions(-) diff --git a/src/heap/heap.cpp b/src/heap/heap.cpp index 01b6cffec8..d70286dd15 100644 --- a/src/heap/heap.cpp +++ b/src/heap/heap.cpp @@ -27,8 +27,6 @@ const unsigned Top = ~static_cast(0); const unsigned InitialGen2CapacityInBytes = 4 * 1024 * 1024; const unsigned InitialTenuredFixieCeilingInBytes = 4 * 1024 * 1024; -const unsigned LowMemoryPaddingInBytes = 1024 * 1024; - const bool Verbose = false; const bool Verbose2 = false; const bool Debug = false; @@ -62,6 +60,7 @@ Aborter* getAborter(Context* c); void* tryAllocate(Context* c, unsigned size); void* allocate(Context* c, unsigned size); +void* allocate(Context* c, unsigned size, bool limit); void free(Context* c, const void* p, unsigned size); #ifdef USE_ATOMIC_OPERATIONS @@ -348,7 +347,8 @@ class Segment { capacity_ = desired; while (data == 0) { data = static_cast - (tryAllocate(context, (footprint(capacity_)) * BytesPerWord)); + (local::allocate + (context, (footprint(capacity_)) * BytesPerWord, false)); if (data == 0) { if (capacity_ > minimum) { @@ -609,7 +609,6 @@ class Context { client(0), count(0), limit(limit), - lowMemoryThreshold(limit / 2), lock(0), immortalHeapStart(0), @@ -680,7 +679,6 @@ class Context { unsigned count; unsigned limit; - unsigned lowMemoryThreshold; System::Mutex* lock; @@ -770,21 +768,6 @@ oversizedGen2(Context* c) and c->gen2.position() < (c->gen2.capacity() / 4); } -inline unsigned -memoryNeeded(Context* c) -{ - return c->count - + ((c->gen1.footprint(minimumNextGen1Capacity(c)) - + c->gen2.footprint(minimumNextGen2Capacity(c))) * BytesPerWord) - + LowMemoryPaddingInBytes; -} - -inline bool -lowMemory(Context* c) -{ - return memoryNeeded(c) > c->lowMemoryThreshold; -} - inline void initNextGen1(Context* c) { @@ -818,7 +801,7 @@ initNextGen2(Context* c) unsigned minimum = minimumNextGen2Capacity(c); unsigned desired = minimum; - if (not (lowMemory(c) or oversizedGen2(c))) { + if (not oversizedGen2(c)) { desired *= 2; } @@ -1666,16 +1649,13 @@ collect2(Context* c) void collect(Context* c) { - if (lowMemory(c) - or oversizedGen2(c) + if (oversizedGen2(c) or c->tenureFootprint + c->tenurePadding > c->gen2.remaining() or c->fixieTenureFootprint + c->tenuredFixieFootprint > c->tenuredFixieCeiling) { if (Verbose) { - if (lowMemory(c)) { - fprintf(stderr, "low memory causes "); - } else if (oversizedGen2(c)) { + if (oversizedGen2(c)) { fprintf(stderr, "oversized gen2 causes "); } else if (c->tenureFootprint + c->tenurePadding > c->gen2.remaining()) { @@ -1699,25 +1679,6 @@ collect(Context* c) then = c->system->now(); } - unsigned count = memoryNeeded(c); - if (count > c->lowMemoryThreshold) { - if (Verbose) { - fprintf(stderr, "increase low memory threshold from %d to %d\n", - c->lowMemoryThreshold, - avg(c->limit, c->lowMemoryThreshold)); - } - - c->lowMemoryThreshold = avg(c->limit, c->lowMemoryThreshold); - } else if (count + (count / 16) < c->lowMemoryThreshold) { - if (Verbose) { - fprintf(stderr, "decrease low memory threshold from %d to %d\n", - c->lowMemoryThreshold, - avg(count, c->lowMemoryThreshold)); - } - - c->lowMemoryThreshold = avg(count, c->lowMemoryThreshold); - } - initNextGen1(c); if (c->mode == Heap::MajorCollection) {