Path: blob/master/test/hotspot/jtreg/runtime/Metaspace/elastic/RandomAllocator.java
41155 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2020 SAP SE. 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 it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 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 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425import java.util.ArrayList;26import java.util.Random;2728/**29* RandomAllocator sits atop an arena and allocates from it.30*31* It will, according to an allocation profile, allocate random blocks in a certain size range and, from time to time,32* deallocate old blocks.33*34* At some point it will reach a limit: either the commit/reserve limit of the underlying MetaspaceTestContext,35* or the allocation ceiling imposed by the test. From that point on allocations will start failing. We can (and do)36* deallocate a bit more, but since that will only exercise the Arena's internal free block list and nothing much else,37* this is unexciting in terms of stressing Metaspace. So, the caller may decide to kill the arena and create a new one.38*39*/40public class RandomAllocator {4142final MetaspaceTestArena arena;43final AllocationProfile profile;4445ArrayList<Allocation> to_dealloc = new ArrayList<>();4647long ticks = 0;48boolean allocationError = false;4950Random localRandom;5152// Roll dice and return true if probability was hit53private boolean rollDice(double probability) {54return ((double)localRandom.nextInt(100) > (100.0 * (1.0 - probability))) ? true : false;55}5657// Allocate a random amount from the arena. If dice hits right, add this to the deallocation list.58void allocateRandomly() {59allocationError = false;60long word_size = profile.randomAllocationSize();61Allocation a = arena.allocate(word_size);62if (a != null) {63if (to_dealloc.size() < 10000) {64to_dealloc.add(a);65}66} else {67allocationError = true;68}69}7071// Randomly choose one of the allocated in the deallocation list and deallocate it72void deallocateRandomly() {73if (to_dealloc.size() == 0) {74return;75}76int n = localRandom.nextInt(to_dealloc.size());77Allocation a = to_dealloc.remove(n);78arena.deallocate(a);79}8081public void tick() {8283if (!allocationError) {84allocateRandomly();85if(rollDice(profile.randomDeallocProbability)) {86deallocateRandomly();87}88} else {89deallocateRandomly();90allocationError = false;91}9293ticks ++;9495}9697public RandomAllocator(MetaspaceTestArena arena) {98this.arena = arena;99this.profile = AllocationProfile.randomProfile();100// reproducable randoms (we assume each allocator is only used from within one thread, and gets created from the main thread).101this.localRandom = new Random(RandomHelper.random().nextInt());102}103104@Override105public String toString() {106return arena.toString() + ", ticks=" + ticks;107}108109}110111112