< prev index next >

test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp

Print this page
rev 60584 : imported patch 8245511-ihop
   1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 #include "precompiled.hpp"
  25 #include "gc/g1/g1CollectedHeap.inline.hpp"
  26 #include "gc/g1/g1IHOPControl.hpp"

  27 #include "gc/g1/g1Predictions.hpp"
  28 #include "unittest.hpp"
  29 
  30 static void test_update(G1IHOPControl* ctrl, double alloc_time,
  31                         size_t alloc_amount, size_t young_size,






















  32                         double mark_time) {



  33   for (int i = 0; i < 100; i++) {
  34     ctrl->update_allocation_info(alloc_time, alloc_amount, young_size);
  35     ctrl->update_marking_length(mark_time);
  36   }
  37 }
  38 
  39 // @requires UseG1GC
  40 TEST_VM(G1StaticIHOPControl, simple) {
  41   // Test requires G1
  42   if (!UseG1GC) {
  43     return;
  44   }
  45 
  46   const size_t initial_ihop = 45;
  47 
  48   G1StaticIHOPControl ctrl(initial_ihop);

  49   ctrl.update_target_occupancy(100);
  50 
  51   size_t threshold = ctrl.get_conc_mark_start_threshold();
  52   EXPECT_EQ(initial_ihop, threshold);
  53 
  54   ctrl.update_allocation_info(100.0, 100, 100);

  55   threshold = ctrl.get_conc_mark_start_threshold();
  56   EXPECT_EQ(initial_ihop, threshold);
  57 
  58   ctrl.update_marking_length(1000.0);
  59   threshold = ctrl.get_conc_mark_start_threshold();
  60   EXPECT_EQ(initial_ihop, threshold);
  61 
  62   // Whatever we pass, the IHOP value must stay the same.
  63   test_update(&ctrl, 2, 10, 10, 3);
  64   threshold = ctrl.get_conc_mark_start_threshold();
  65 
  66   EXPECT_EQ(initial_ihop, threshold);
  67 
  68   test_update(&ctrl, 12, 10, 10, 3);
  69   threshold = ctrl.get_conc_mark_start_threshold();
  70 
  71   EXPECT_EQ(initial_ihop, threshold);
  72 }
  73 
  74 // @requires UseG1GC
  75 TEST_VM(G1AdaptiveIHOPControl, simple) {
  76   // Test requires G1
  77   if (!UseG1GC) {
  78     return;
  79   }
  80 
  81   const size_t initial_threshold = 45;
  82   const size_t young_size = 10;
  83   const size_t target_size = 100;
  84 
  85   // The final IHOP value is always
  86   // target_size - (young_size + alloc_amount/alloc_time * marking_time)
  87 

  88   G1Predictions pred(0.95);
  89   G1AdaptiveIHOPControl ctrl(initial_threshold, &pred, 0, 0);
  90   ctrl.update_target_occupancy(target_size);
  91 
  92   // First "load".
  93   const size_t alloc_time1 = 2;
  94   const size_t alloc_amount1 = 10;
  95   const size_t marking_time1 = 2;
  96   const size_t settled_ihop1 = target_size
  97           - (young_size + alloc_amount1 / alloc_time1 * marking_time1);
  98 
  99   size_t threshold;
 100   threshold = ctrl.get_conc_mark_start_threshold();
 101 
 102   EXPECT_EQ(initial_threshold, threshold);
 103 
 104   for (size_t i = 0; i < G1AdaptiveIHOPNumInitialSamples - 1; i++) {
 105     ctrl.update_allocation_info(alloc_time1, alloc_amount1, young_size);

 106     ctrl.update_marking_length(marking_time1);
 107     // Not enough data yet.
 108     threshold = ctrl.get_conc_mark_start_threshold();
 109 
 110     ASSERT_EQ(initial_threshold, threshold) << "on step " << i;
 111   }
 112 
 113   test_update(&ctrl, alloc_time1, alloc_amount1, young_size, marking_time1);
 114 
 115   threshold = ctrl.get_conc_mark_start_threshold();
 116 
 117   EXPECT_EQ(settled_ihop1, threshold);
 118 
 119   // Second "load". A bit higher allocation rate.
 120   const size_t alloc_time2 = 2;
 121   const size_t alloc_amount2 = 30;
 122   const size_t marking_time2 = 2;
 123   const size_t settled_ihop2 = target_size
 124           - (young_size + alloc_amount2 / alloc_time2 * marking_time2);
 125 
 126   test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2);
 127 
 128   threshold = ctrl.get_conc_mark_start_threshold();
 129 
 130   EXPECT_LT(threshold, settled_ihop1);
 131 
 132   // Third "load". Very high (impossible) allocation rate.
 133   const size_t alloc_time3 = 1;
 134   const size_t alloc_amount3 = 50;
 135   const size_t marking_time3 = 2;
 136   const size_t settled_ihop3 = 0;
 137 
 138   test_update(&ctrl, alloc_time3, alloc_amount3, young_size, marking_time3);
 139   threshold = ctrl.get_conc_mark_start_threshold();
 140 
 141   EXPECT_EQ(settled_ihop3, threshold);
 142 
 143   // And back to some arbitrary value.
 144   test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2);
 145 
 146   threshold = ctrl.get_conc_mark_start_threshold();
 147 
 148   EXPECT_GT(threshold, settled_ihop3);
 149 }



































































   1 /*
   2  * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 #include "precompiled.hpp"
  25 #include "gc/g1/g1CollectedHeap.inline.hpp"
  26 #include "gc/g1/g1IHOPControl.hpp"
  27 #include "gc/g1/g1OldGenAllocationTracker.hpp"
  28 #include "gc/g1/g1Predictions.hpp"
  29 #include "unittest.hpp"
  30 
  31 static void test_update_allocation_tracker(G1OldGenAllocationTracker* alloc_tracker,
  32                                            size_t alloc_amount) {
  33   alloc_tracker->add_allocated_bytes_since_last_gc(alloc_amount);
  34   alloc_tracker->reset_after_gc((size_t)0);
  35 }
  36 
  37 static void test_update(G1IHOPControl* ctrl,
  38                         G1OldGenAllocationTracker* alloc_tracker,
  39                         double alloc_time, size_t alloc_amount,
  40                         size_t young_size, double mark_time) {
  41   test_update_allocation_tracker(alloc_tracker, alloc_amount);
  42   for (int i = 0; i < 100; i++) {
  43     ctrl->update_allocation_info(alloc_time, young_size);
  44     ctrl->update_marking_length(mark_time);
  45   }
  46 }
  47 
  48 static void test_update_humongous(G1IHOPControl* ctrl,
  49                                   G1OldGenAllocationTracker* alloc_tracker,
  50                                   double alloc_time,
  51                                   size_t alloc_amount_non_hum,
  52                                   size_t alloc_amount_hum,
  53                                   size_t humongous_bytes_after_last_gc,
  54                                   size_t young_size,
  55                                   double mark_time) {
  56   alloc_tracker->add_allocated_bytes_since_last_gc(alloc_amount_non_hum);
  57   alloc_tracker->add_allocated_humongous_bytes_since_last_gc(alloc_amount_hum);
  58   alloc_tracker->reset_after_gc(humongous_bytes_after_last_gc);
  59   for (int i = 0; i < 100; i++) {
  60     ctrl->update_allocation_info(alloc_time, young_size);
  61     ctrl->update_marking_length(mark_time);
  62   }
  63 }
  64 
  65 // @requires UseG1GC
  66 TEST_VM(G1StaticIHOPControl, simple) {
  67   // Test requires G1
  68   if (!UseG1GC) {
  69     return;
  70   }
  71 
  72   const size_t initial_ihop = 45;
  73 
  74   G1OldGenAllocationTracker alloc_tracker;
  75   G1StaticIHOPControl ctrl(initial_ihop, &alloc_tracker);
  76   ctrl.update_target_occupancy(100);
  77 
  78   size_t threshold = ctrl.get_conc_mark_start_threshold();
  79   EXPECT_EQ(initial_ihop, threshold);
  80 
  81   test_update_allocation_tracker(&alloc_tracker, 100);
  82   ctrl.update_allocation_info(100.0, 100);
  83   threshold = ctrl.get_conc_mark_start_threshold();
  84   EXPECT_EQ(initial_ihop, threshold);
  85 
  86   ctrl.update_marking_length(1000.0);
  87   threshold = ctrl.get_conc_mark_start_threshold();
  88   EXPECT_EQ(initial_ihop, threshold);
  89 
  90   // Whatever we pass, the IHOP value must stay the same.
  91   test_update(&ctrl, &alloc_tracker, 2, 10, 10, 3);
  92   threshold = ctrl.get_conc_mark_start_threshold();
  93 
  94   EXPECT_EQ(initial_ihop, threshold);
  95 
  96   test_update(&ctrl, &alloc_tracker, 12, 10, 10, 3);
  97   threshold = ctrl.get_conc_mark_start_threshold();
  98 
  99   EXPECT_EQ(initial_ihop, threshold);
 100 }
 101 
 102 // @requires UseG1GC
 103 TEST_VM(G1AdaptiveIHOPControl, simple) {
 104   // Test requires G1
 105   if (!UseG1GC) {
 106     return;
 107   }
 108 
 109   const size_t initial_threshold = 45;
 110   const size_t young_size = 10;
 111   const size_t target_size = 100;
 112 
 113   // The final IHOP value is always
 114   // target_size - (young_size + alloc_amount/alloc_time * marking_time)
 115 
 116   G1OldGenAllocationTracker alloc_tracker;
 117   G1Predictions pred(0.95);
 118   G1AdaptiveIHOPControl ctrl(initial_threshold, &alloc_tracker, &pred, 0, 0);
 119   ctrl.update_target_occupancy(target_size);
 120 
 121   // First "load".
 122   const size_t alloc_time1 = 2;
 123   const size_t alloc_amount1 = 10;
 124   const size_t marking_time1 = 2;
 125   const size_t settled_ihop1 = target_size
 126           - (young_size + alloc_amount1 / alloc_time1 * marking_time1);
 127 
 128   size_t threshold;
 129   threshold = ctrl.get_conc_mark_start_threshold();
 130 
 131   EXPECT_EQ(initial_threshold, threshold);
 132 
 133   for (size_t i = 0; i < G1AdaptiveIHOPNumInitialSamples - 1; i++) {
 134     test_update_allocation_tracker(&alloc_tracker, alloc_amount1);
 135     ctrl.update_allocation_info(alloc_time1, young_size);
 136     ctrl.update_marking_length(marking_time1);
 137     // Not enough data yet.
 138     threshold = ctrl.get_conc_mark_start_threshold();
 139 
 140     ASSERT_EQ(initial_threshold, threshold) << "on step " << i;
 141   }
 142 
 143   test_update(&ctrl, &alloc_tracker, alloc_time1, alloc_amount1, young_size, marking_time1);
 144 
 145   threshold = ctrl.get_conc_mark_start_threshold();
 146 
 147   EXPECT_EQ(settled_ihop1, threshold);
 148 
 149   // Second "load". A bit higher allocation rate.
 150   const size_t alloc_time2 = 2;
 151   const size_t alloc_amount2 = 30;
 152   const size_t marking_time2 = 2;
 153   const size_t settled_ihop2 = target_size
 154           - (young_size + alloc_amount2 / alloc_time2 * marking_time2);
 155 
 156   test_update(&ctrl, &alloc_tracker, alloc_time2, alloc_amount2, young_size, marking_time2);
 157 
 158   threshold = ctrl.get_conc_mark_start_threshold();
 159 
 160   EXPECT_LT(threshold, settled_ihop1);
 161 
 162   // Third "load". Very high (impossible) allocation rate.
 163   const size_t alloc_time3 = 1;
 164   const size_t alloc_amount3 = 50;
 165   const size_t marking_time3 = 2;
 166   const size_t settled_ihop3 = 0;
 167 
 168   test_update(&ctrl, &alloc_tracker, alloc_time3, alloc_amount3, young_size, marking_time3);
 169   threshold = ctrl.get_conc_mark_start_threshold();
 170 
 171   EXPECT_EQ(settled_ihop3, threshold);
 172 
 173   // And back to some arbitrary value.
 174   test_update(&ctrl, &alloc_tracker, alloc_time2, alloc_amount2, young_size, marking_time2);
 175 
 176   threshold = ctrl.get_conc_mark_start_threshold();
 177 
 178   EXPECT_GT(threshold, settled_ihop3);
 179 }
 180 
 181 TEST_VM(G1AdaptiveIHOPControl, humongous) {
 182   // Test requires G1
 183   if (!UseG1GC) {
 184     return;
 185   }
 186 
 187   const size_t initial_threshold = 45;
 188   const size_t young_size = 10;
 189   const size_t target_size = 100;
 190   const double duration = 10.0;
 191   const size_t marking_time = 2; 
 192 
 193   G1OldGenAllocationTracker alloc_tracker;
 194   G1Predictions pred(0.95);
 195   G1AdaptiveIHOPControl ctrl(initial_threshold, &alloc_tracker, &pred, 0, 0);
 196   ctrl.update_target_occupancy(target_size);
 197 
 198   size_t old_bytes = 100;
 199   size_t humongous_bytes = 200;
 200   size_t humongous_bytes_after_gc = 150;
 201   size_t humongous_bytes_after_last_gc = 50;
 202   // Load 1
 203   test_update_humongous(&ctrl, &alloc_tracker, duration, 0, humongous_bytes,
 204                         humongous_bytes_after_last_gc, young_size, marking_time);
 205   // Test threshold
 206   size_t threshold;
 207   threshold = ctrl.get_conc_mark_start_threshold();
 208   // Adjusted allocated bytes:
 209   // Total bytes: humongous_bytes
 210   // Freed hum bytes: humongous_bytes - humongous_bytes_after_last_gc
 211   double alloc_rate = humongous_bytes_after_last_gc / duration; 
 212   size_t target_threshold = target_size - (size_t)(young_size + alloc_rate * marking_time);
 213 
 214   EXPECT_EQ(threshold, target_threshold);
 215 
 216   // Load 2
 217   G1AdaptiveIHOPControl ctrl2(initial_threshold, &alloc_tracker, &pred, 0, 0);
 218   ctrl2.update_target_occupancy(target_size);
 219   test_update_humongous(&ctrl2, &alloc_tracker, duration, old_bytes, humongous_bytes,
 220                         humongous_bytes_after_gc, young_size, marking_time);
 221   threshold = ctrl2.get_conc_mark_start_threshold(); 
 222   // Adjusted allocated bytes:
 223   // Total bytes: old_bytes + humongous_bytes
 224   // Freed hum bytes: humongous_bytes - (humongous_bytes_after_gc - humongous_bytes_after_last_gc)
 225   alloc_rate = (old_bytes + (humongous_bytes_after_gc - humongous_bytes_after_last_gc)) / duration;
 226   target_threshold = target_size - (size_t)(young_size + alloc_rate * marking_time);
 227 
 228   EXPECT_EQ(threshold, target_threshold);
 229 
 230   // Load 3
 231   humongous_bytes_after_last_gc = humongous_bytes_after_gc;
 232   humongous_bytes_after_gc = 50;
 233   G1AdaptiveIHOPControl ctrl3(initial_threshold, &alloc_tracker, &pred, 0, 0);
 234   ctrl3.update_target_occupancy(target_size);
 235   test_update_humongous(&ctrl3, &alloc_tracker, duration, old_bytes, humongous_bytes,
 236                         humongous_bytes_after_gc, young_size, marking_time);
 237   threshold = ctrl3.get_conc_mark_start_threshold();
 238   // Adjusted allocated bytes:
 239   // All humongous are cleaned up since humongous_bytes_after_gc < humongous_bytes_after_last_gc
 240   // Total bytes: old_bytes + humongous_bytes
 241   // Freed hum bytes: humongous_bytes 
 242   alloc_rate = old_bytes / duration;
 243   target_threshold = target_size - (size_t)(young_size + alloc_rate * marking_time);
 244   
 245   EXPECT_EQ(threshold, target_threshold);
 246 }
< prev index next >