Make sure that idle scavenges are just performed when enough objects are allocated...
authorhpayer <hpayer@chromium.org>
Fri, 15 May 2015 16:06:21 +0000 (09:06 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 15 May 2015 16:06:08 +0000 (16:06 +0000)
BUG=

Review URL: https://codereview.chromium.org/1138643003

Cr-Commit-Position: refs/heads/master@{#28428}

src/heap/gc-idle-time-handler.cc
src/heap/gc-idle-time-handler.h
test/unittests/heap/gc-idle-time-handler-unittest.cc

index 19c9dab..40c2eff 100644 (file)
@@ -122,8 +122,8 @@ bool GCIdleTimeHandler::ShouldDoScavenge(
     new_space_allocation_limit = new_space_size;
   }
 
-  // We do not know the allocation throughput before the first Scavenge.
-  // TODO(hpayer): Estimate allocation throughput before the first Scavenge.
+  // We do not know the allocation throughput before the first scavenge.
+  // TODO(hpayer): Estimate allocation throughput before the first scavenge.
   if (new_space_allocation_throughput_in_bytes_per_ms == 0) {
     new_space_allocation_limit =
         static_cast<size_t>(new_space_size * kConservativeTimeRatio);
@@ -131,10 +131,17 @@ bool GCIdleTimeHandler::ShouldDoScavenge(
     // We have to trigger scavenge before we reach the end of new space.
     size_t adjust_limit = new_space_allocation_throughput_in_bytes_per_ms *
                           kTimeUntilNextIdleEvent;
-    if (adjust_limit > new_space_allocation_limit)
+    if (adjust_limit > new_space_allocation_limit) {
       new_space_allocation_limit = 0;
-    else
+    } else {
       new_space_allocation_limit -= adjust_limit;
+    }
+  }
+
+  // The allocated new space limit to trigger a scavange has to be at least
+  // kMinimumNewSpaceSizeToPerformScavenge.
+  if (new_space_allocation_limit < kMinimumNewSpaceSizeToPerformScavenge) {
+    new_space_allocation_limit = kMinimumNewSpaceSizeToPerformScavenge;
   }
 
   if (scavenge_speed_in_bytes_per_ms == 0) {
@@ -245,8 +252,8 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms,
 // a full GC.
 // (2) If the context disposal rate is high and we cannot perform a full GC,
 // we do nothing until the context disposal rate becomes lower.
-// (3) If the new space is almost full and we can affort a Scavenge or if the
-// next Scavenge will very likely take long, then a Scavenge is performed.
+// (3) If the new space is almost full and we can affort a scavenge or if the
+// next scavenge will very likely take long, then a scavenge is performed.
 // (4) If there is currently no MarkCompact idle round going on, we start a
 // new idle round if enough garbage was created. Otherwise we do not perform
 // garbage collection to keep system utilization low.
index 3beee16..e76178b 100644 (file)
@@ -136,6 +136,9 @@ class GCIdleTimeHandler {
   // lower bound for the scavenger speed.
   static const size_t kInitialConservativeScavengeSpeed = 100 * KB;
 
+  // The minimum size of allocated new space objects to trigger a scavenge.
+  static const size_t kMinimumNewSpaceSizeToPerformScavenge = MB / 2;
+
   // If contexts are disposed at a higher rate a full gc is triggered.
   static const double kHighContextDisposalRate;
 
index 011fdc0..357b08f 100644 (file)
@@ -219,6 +219,18 @@ TEST_F(GCIdleTimeHandlerTest, DoScavengeHighScavengeSpeed) {
 }
 
 
+TEST_F(GCIdleTimeHandlerTest, DoNotScavengeSmallNewSpaceSize) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.used_new_space_size = (MB / 2) - 1;
+  heap_state.scavenge_speed_in_bytes_per_ms = kNewSpaceCapacity;
+  int idle_time_ms = 16;
+  EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
+      idle_time_ms, heap_state.new_space_capacity,
+      heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
+      heap_state.new_space_allocation_throughput_in_bytes_per_ms));
+}
+
+
 TEST_F(GCIdleTimeHandlerTest, ShouldDoMarkCompact) {
   size_t idle_time_ms = GCIdleTimeHandler::kMaxScheduledIdleTime;
   EXPECT_TRUE(GCIdleTimeHandler::ShouldDoMarkCompact(idle_time_ms, 0, 0));