Path: blob/master/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp
41149 views
/*1* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"24#include "gc/g1/g1CollectedHeap.inline.hpp"25#include "gc/g1/g1IHOPControl.hpp"26#include "gc/g1/g1OldGenAllocationTracker.hpp"27#include "gc/g1/g1Predictions.hpp"28#include "unittest.hpp"2930static void test_update_allocation_tracker(G1OldGenAllocationTracker* alloc_tracker,31size_t alloc_amount) {32alloc_tracker->add_allocated_bytes_since_last_gc(alloc_amount);33alloc_tracker->reset_after_gc((size_t)0);34}3536static void test_update(G1IHOPControl* ctrl,37G1OldGenAllocationTracker* alloc_tracker,38double alloc_time, size_t alloc_amount,39size_t young_size, double mark_time) {40test_update_allocation_tracker(alloc_tracker, alloc_amount);41for (int i = 0; i < 100; i++) {42ctrl->update_allocation_info(alloc_time, young_size);43ctrl->update_marking_length(mark_time);44}45}4647static void test_update_humongous(G1IHOPControl* ctrl,48G1OldGenAllocationTracker* alloc_tracker,49double alloc_time,50size_t alloc_amount_non_hum,51size_t alloc_amount_hum,52size_t humongous_bytes_after_last_gc,53size_t young_size,54double mark_time) {55alloc_tracker->add_allocated_bytes_since_last_gc(alloc_amount_non_hum);56alloc_tracker->add_allocated_humongous_bytes_since_last_gc(alloc_amount_hum);57alloc_tracker->reset_after_gc(humongous_bytes_after_last_gc);58for (int i = 0; i < 100; i++) {59ctrl->update_allocation_info(alloc_time, young_size);60ctrl->update_marking_length(mark_time);61}62}6364// @requires UseG1GC65TEST_VM(G1StaticIHOPControl, simple) {66// Test requires G167if (!UseG1GC) {68return;69}7071const size_t initial_ihop = 45;7273G1OldGenAllocationTracker alloc_tracker;74G1StaticIHOPControl ctrl(initial_ihop, &alloc_tracker);75ctrl.update_target_occupancy(100);7677size_t threshold = ctrl.get_conc_mark_start_threshold();78EXPECT_EQ(initial_ihop, threshold);7980test_update_allocation_tracker(&alloc_tracker, 100);81ctrl.update_allocation_info(100.0, 100);82threshold = ctrl.get_conc_mark_start_threshold();83EXPECT_EQ(initial_ihop, threshold);8485ctrl.update_marking_length(1000.0);86threshold = ctrl.get_conc_mark_start_threshold();87EXPECT_EQ(initial_ihop, threshold);8889// Whatever we pass, the IHOP value must stay the same.90test_update(&ctrl, &alloc_tracker, 2, 10, 10, 3);91threshold = ctrl.get_conc_mark_start_threshold();9293EXPECT_EQ(initial_ihop, threshold);9495test_update(&ctrl, &alloc_tracker, 12, 10, 10, 3);96threshold = ctrl.get_conc_mark_start_threshold();9798EXPECT_EQ(initial_ihop, threshold);99}100101// @requires UseG1GC102TEST_VM(G1AdaptiveIHOPControl, simple) {103// Test requires G1104if (!UseG1GC) {105return;106}107108const size_t initial_threshold = 45;109const size_t young_size = 10;110const size_t target_size = 100;111112// The final IHOP value is always113// target_size - (young_size + alloc_amount/alloc_time * marking_time)114115G1OldGenAllocationTracker alloc_tracker;116G1Predictions pred(0.95);117G1AdaptiveIHOPControl ctrl(initial_threshold, &alloc_tracker, &pred, 0, 0);118ctrl.update_target_occupancy(target_size);119120// First "load".121const size_t alloc_time1 = 2;122const size_t alloc_amount1 = 10;123const size_t marking_time1 = 2;124const size_t settled_ihop1 = target_size125- (young_size + alloc_amount1 / alloc_time1 * marking_time1);126127size_t threshold;128threshold = ctrl.get_conc_mark_start_threshold();129130EXPECT_EQ(initial_threshold, threshold);131132for (size_t i = 0; i < G1AdaptiveIHOPNumInitialSamples - 1; i++) {133test_update_allocation_tracker(&alloc_tracker, alloc_amount1);134ctrl.update_allocation_info(alloc_time1, young_size);135ctrl.update_marking_length(marking_time1);136// Not enough data yet.137threshold = ctrl.get_conc_mark_start_threshold();138139ASSERT_EQ(initial_threshold, threshold) << "on step " << i;140}141142test_update(&ctrl, &alloc_tracker, alloc_time1, alloc_amount1, young_size, marking_time1);143144threshold = ctrl.get_conc_mark_start_threshold();145146EXPECT_EQ(settled_ihop1, threshold);147148// Second "load". A bit higher allocation rate.149const size_t alloc_time2 = 2;150const size_t alloc_amount2 = 30;151const size_t marking_time2 = 2;152const size_t settled_ihop2 = target_size153- (young_size + alloc_amount2 / alloc_time2 * marking_time2);154155test_update(&ctrl, &alloc_tracker, alloc_time2, alloc_amount2, young_size, marking_time2);156157threshold = ctrl.get_conc_mark_start_threshold();158159EXPECT_LT(threshold, settled_ihop1);160161// Third "load". Very high (impossible) allocation rate.162const size_t alloc_time3 = 1;163const size_t alloc_amount3 = 50;164const size_t marking_time3 = 2;165const size_t settled_ihop3 = 0;166167test_update(&ctrl, &alloc_tracker, alloc_time3, alloc_amount3, young_size, marking_time3);168threshold = ctrl.get_conc_mark_start_threshold();169170EXPECT_EQ(settled_ihop3, threshold);171172// And back to some arbitrary value.173test_update(&ctrl, &alloc_tracker, alloc_time2, alloc_amount2, young_size, marking_time2);174175threshold = ctrl.get_conc_mark_start_threshold();176177EXPECT_GT(threshold, settled_ihop3);178}179180TEST_VM(G1AdaptiveIHOPControl, humongous) {181// Test requires G1182if (!UseG1GC) {183return;184}185186const size_t initial_threshold = 45;187const size_t young_size = 10;188const size_t target_size = 100;189const double duration = 10.0;190const size_t marking_time = 2;191192G1OldGenAllocationTracker alloc_tracker;193G1Predictions pred(0.95);194G1AdaptiveIHOPControl ctrl(initial_threshold, &alloc_tracker, &pred, 0, 0);195ctrl.update_target_occupancy(target_size);196197size_t old_bytes = 100;198size_t humongous_bytes = 200;199size_t humongous_bytes_after_gc = 150;200size_t humongous_bytes_after_last_gc = 50;201// Load 1202test_update_humongous(&ctrl, &alloc_tracker, duration, 0, humongous_bytes,203humongous_bytes_after_last_gc, young_size, marking_time);204// Test threshold205size_t threshold;206threshold = ctrl.get_conc_mark_start_threshold();207// Adjusted allocated bytes:208// Total bytes: humongous_bytes209// Freed hum bytes: humongous_bytes - humongous_bytes_after_last_gc210double alloc_rate = humongous_bytes_after_last_gc / duration;211size_t target_threshold = target_size - (size_t)(young_size + alloc_rate * marking_time);212213EXPECT_EQ(threshold, target_threshold);214215// Load 2216G1AdaptiveIHOPControl ctrl2(initial_threshold, &alloc_tracker, &pred, 0, 0);217ctrl2.update_target_occupancy(target_size);218test_update_humongous(&ctrl2, &alloc_tracker, duration, old_bytes, humongous_bytes,219humongous_bytes_after_gc, young_size, marking_time);220threshold = ctrl2.get_conc_mark_start_threshold();221// Adjusted allocated bytes:222// Total bytes: old_bytes + humongous_bytes223// Freed hum bytes: humongous_bytes - (humongous_bytes_after_gc - humongous_bytes_after_last_gc)224alloc_rate = (old_bytes + (humongous_bytes_after_gc - humongous_bytes_after_last_gc)) / duration;225target_threshold = target_size - (size_t)(young_size + alloc_rate * marking_time);226227EXPECT_EQ(threshold, target_threshold);228229// Load 3230humongous_bytes_after_last_gc = humongous_bytes_after_gc;231humongous_bytes_after_gc = 50;232G1AdaptiveIHOPControl ctrl3(initial_threshold, &alloc_tracker, &pred, 0, 0);233ctrl3.update_target_occupancy(target_size);234test_update_humongous(&ctrl3, &alloc_tracker, duration, old_bytes, humongous_bytes,235humongous_bytes_after_gc, young_size, marking_time);236threshold = ctrl3.get_conc_mark_start_threshold();237// Adjusted allocated bytes:238// All humongous are cleaned up since humongous_bytes_after_gc < humongous_bytes_after_last_gc239// Total bytes: old_bytes + humongous_bytes240// Freed hum bytes: humongous_bytes241alloc_rate = old_bytes / duration;242target_threshold = target_size - (size_t)(young_size + alloc_rate * marking_time);243244EXPECT_EQ(threshold, target_threshold);245}246247248