Skip to content

Commit

Permalink
8302385: Remove MetaspaceReclaimPolicy=none
Browse files Browse the repository at this point in the history
Reviewed-by: iklam, dholmes
  • Loading branch information
tstuefe committed Feb 16, 2023
1 parent 6e2d3c6 commit 519229d
Show file tree
Hide file tree
Showing 19 changed files with 98 additions and 252 deletions.
27 changes: 12 additions & 15 deletions src/hotspot/share/memory/metaspace/chunkManager.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022 SAP SE. All rights reserved.
* Copyright (c) 2018, 2023 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -206,11 +206,10 @@ Metachunk* ChunkManager::get_chunk_locked(chunklevel_t preferred_level, chunklev
split_chunk_and_add_splinters(c, preferred_level);
assert(c->level() == preferred_level, "split failed?");
}
// Attempt to commit the chunk (depending on settings, we either fully commit it or just
// commit enough to get the caller going). That may fail if we hit a commit limit. In
// Attempt to commit the chunk. That may fail if we hit a commit limit. In
// that case put the chunk back to the freelist (re-merging it with its neighbors if we
// did split it) and return null.
const size_t to_commit = Settings::new_chunks_are_fully_committed() ? c->word_size() : min_committed_words;
const size_t to_commit = min_committed_words;
if (c->committed_words() < to_commit) {
if (c->ensure_committed_locked(to_commit) == false) {
UL2(info, "failed to commit " SIZE_FORMAT " words on chunk " METACHUNK_FORMAT ".",
Expand Down Expand Up @@ -343,17 +342,15 @@ void ChunkManager::purge() {
// free chunks and uncommit the backing memory of those large enough to
// contain one or multiple commit granules (chunks larger than a granule
// always cover a whole number of granules and start at a granule boundary).
if (Settings::uncommit_free_chunks()) {
const chunklevel_t max_level =
chunklevel::level_fitting_word_size(Settings::commit_granule_words());
for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL;
l <= max_level;
l++) {
// Since we uncommit all chunks at this level, we do not break the "committed chunks are
// at the front of the list" condition.
for (Metachunk* c = _chunks.first_at_level(l); c != nullptr; c = c->next()) {
c->uncommit_locked();
}
const chunklevel_t max_level =
chunklevel::level_fitting_word_size(Settings::commit_granule_words());
for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL;
l <= max_level;
l++) {
// Since we uncommit all chunks at this level, we do not break the "committed chunks are
// at the front of the list" condition.
for (Metachunk* c = _chunks.first_at_level(l); c != nullptr; c = c->next()) {
c->uncommit_locked();
}
}

Expand Down
11 changes: 1 addition & 10 deletions src/hotspot/share/memory/metaspace/freeChunkList.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -52,15 +52,6 @@ namespace metaspace {
// committed word size. We stop searching at the first fully uncommitted
// chunk.
//
// Note that even though this is an O(n) search, partially committed chunks are
// very rare. A partially committed chunk is one spanning multiple commit
// granules, of which some are committed and some are not.
// If metaspace reclamation is on (MetaspaceReclaimPolicy=balanced|aggressive), these
// chunks will become uncommitted after they are returned to the ChunkManager.
// If metaspace reclamation is off (MetaspaceReclaimPolicy=none) they are fully
// committed when handed out and will not be uncommitted when returned to the
// ChunkManager.
//
// Therefore in all likelihood the chunk lists only contain fully committed or
// fully uncommitted chunks; either way search will stop at the first chunk.

Expand Down
5 changes: 1 addition & 4 deletions src/hotspot/share/memory/metaspace/metaspaceArena.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -316,9 +316,6 @@ MetaWord* MetaspaceArena::allocate_inner(size_t requested_word_size) {
METACHUNK_FORMAT_ARGS(new_chunk), requested_word_size);

assert(new_chunk->free_below_committed_words() >= raw_word_size, "Sanity");
if (Settings::new_chunks_are_fully_committed()) {
assert(new_chunk->is_fully_committed(), "Chunk should be fully committed.");
}

// We have a new chunk. Before making it the current chunk, retire the old one.
if (current_chunk() != nullptr) {
Expand Down
21 changes: 2 additions & 19 deletions src/hotspot/share/memory/metaspace/metaspaceSettings.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -39,34 +39,19 @@ namespace metaspace {
size_t Settings::_commit_granule_bytes = 0;
size_t Settings::_commit_granule_words = 0;

bool Settings::_new_chunks_are_fully_committed = false;
bool Settings::_uncommit_free_chunks = false;

DEBUG_ONLY(bool Settings::_use_allocation_guard = false;)

void Settings::ergo_initialize() {
if (strcmp(MetaspaceReclaimPolicy, "none") == 0) {
log_info(metaspace)("Initialized with strategy: no reclaim.");
_commit_granule_bytes = MAX2(os::vm_page_size(), 64 * K);
_commit_granule_words = _commit_granule_bytes / BytesPerWord;
// In "none" reclamation mode, we do not uncommit, and we commit new chunks fully;
// that very closely mimics the behaviour of old Metaspace.
_new_chunks_are_fully_committed = true;
_uncommit_free_chunks = false;
} else if (strcmp(MetaspaceReclaimPolicy, "aggressive") == 0) {
if (strcmp(MetaspaceReclaimPolicy, "aggressive") == 0) {
log_info(metaspace)("Initialized with strategy: aggressive reclaim.");
// Set the granule size rather small; may increase
// mapping fragmentation but also increase chance to uncommit.
_commit_granule_bytes = MAX2(os::vm_page_size(), 16 * K);
_commit_granule_words = _commit_granule_bytes / BytesPerWord;
_new_chunks_are_fully_committed = false;
_uncommit_free_chunks = true;
} else if (strcmp(MetaspaceReclaimPolicy, "balanced") == 0) {
log_info(metaspace)("Initialized with strategy: balanced reclaim.");
_commit_granule_bytes = MAX2(os::vm_page_size(), 64 * K);
_commit_granule_words = _commit_granule_bytes / BytesPerWord;
_new_chunks_are_fully_committed = false;
_uncommit_free_chunks = true;
} else {
vm_exit_during_initialization("Invalid value for MetaspaceReclaimPolicy: \"%s\".", MetaspaceReclaimPolicy);
}
Expand All @@ -87,8 +72,6 @@ void Settings::print_on(outputStream* st) {
st->print_cr(" - commit_granule_words: " SIZE_FORMAT ".", commit_granule_words());
st->print_cr(" - virtual_space_node_default_size: " SIZE_FORMAT ".", virtual_space_node_default_word_size());
st->print_cr(" - enlarge_chunks_in_place: %d.", (int)enlarge_chunks_in_place());
st->print_cr(" - new_chunks_are_fully_committed: %d.", (int)new_chunks_are_fully_committed());
st->print_cr(" - uncommit_free_chunks: %d.", (int)uncommit_free_chunks());
st->print_cr(" - use_allocation_guard: %d.", (int)use_allocation_guard());
}

Expand Down
15 changes: 2 additions & 13 deletions src/hotspot/share/memory/metaspace/metaspaceSettings.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -56,27 +56,16 @@ class Settings : public AllStatic {
// the requested size, we attempt to double the chunk size in place...
static const bool _enlarge_chunks_in_place = true;

// Whether or not chunks handed out to an arena start out fully committed;
// if true, this deactivates committing-on-demand (regardless of whether
// we uncommit free chunks).
static bool _new_chunks_are_fully_committed;

// If true, chunks equal or larger than a commit granule are uncommitted
// after being returned to the freelist.
static bool _uncommit_free_chunks;

// If true, metablock allocations are guarded and periodically checked.
DEBUG_ONLY(static bool _use_allocation_guard;)

public:

static size_t commit_granule_bytes() { return _commit_granule_bytes; }
static size_t commit_granule_words() { return _commit_granule_words; }
static bool new_chunks_are_fully_committed() { return _new_chunks_are_fully_committed; }
static size_t virtual_space_node_default_word_size() { return _virtual_space_node_default_word_size; }
static size_t virtual_space_node_reserve_alignment_words() { return _virtual_space_node_reserve_alignment_words; }
static bool enlarge_chunks_in_place() { return _enlarge_chunks_in_place; }
static bool uncommit_free_chunks() { return _uncommit_free_chunks; }
static bool use_allocation_guard() { return DEBUG_ONLY(_use_allocation_guard) NOT_DEBUG(false); }

static void ergo_initialize();
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/runtime/globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1421,7 +1421,7 @@ const int ObjectAlignmentInBytes = 8;
"fails VM initialization (requires -Xshare=off.") \
\
product(ccstr, MetaspaceReclaimPolicy, "balanced", DIAGNOSTIC, \
"options: balanced, aggressive, none") \
"options: balanced, aggressive") \
\
product(bool, PrintMetaspaceStatisticsAtExit, false, DIAGNOSTIC, \
"Print metaspace statistics upon VM exit.") \
Expand Down
7 changes: 2 additions & 5 deletions test/hotspot/gtest/metaspace/metaspaceGtestContexts.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2023 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -66,9 +66,6 @@ void ChunkGtestContext::checked_alloc_chunk_0(Metachunk** p_return_value, chunkl
// Needs lock EXPECT_NULL(c->prev_in_vs());
ASSERT_TRUE(c->is_root_chunk() || c->is_leader());
}
if (Settings::new_chunks_are_fully_committed()) {
ASSERT_TRUE(c->is_fully_committed());
}

_num_chunks_allocated++;

Expand Down
9 changes: 2 additions & 7 deletions test/hotspot/gtest/metaspace/test_chunkManager_stress.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -71,11 +71,6 @@ class ChunkManagerRandomChunkAllocTest {

// could it be commit limit hit?

if (Settings::new_chunks_are_fully_committed()) {
// For all we know we may have just failed to fully-commit a new root chunk.
additional_word_size = MAX_CHUNK_WORD_SIZE;
}

// Note that this is difficult to verify precisely, since there are
// several layers of truth:
// a) at the lowest layer (RootChunkArea) we have a bitmap of committed granules;
Expand Down
22 changes: 2 additions & 20 deletions test/hotspot/gtest/metaspace/test_metachunk.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -82,19 +82,6 @@ TEST_VM(metaspace, get_chunk_with_commit_limit) {
// When should commit work? As long as min_committed_words is smaller than commit_limit_words.
bool commit_should_work = min_committed_words <= commit_limit_words;

// Exception: MetaspaceReclaimPolicy=none. Here, chunks are fully committed from the get go and
// min_committed_words is effectively ignored. So commit would fail if the chunk is larger than
// the commit limit. Unfortunately, the chunk size is difficult to predict (it will be between
// [pref_lvl, max_lvl]. To make matters simple, we skip the test if we don't know the level for
// sure.
if (Settings::new_chunks_are_fully_committed()) {
if (pref_lvl == max_lvl) {
commit_should_work = word_size_for_level(max_lvl) <= commit_limit_words;
} else {
continue;
}
}

// printf("commit_limit: " SIZE_FORMAT ", min_committed_words: " SIZE_FORMAT
// ", max chunk level: " CHKLVL_FORMAT ", preferred chunk level: " CHKLVL_FORMAT ", should work: %d\n",
// commit_limit_words, min_committed_words, max_lvl, pref_lvl, commit_should_work);
Expand Down Expand Up @@ -242,11 +229,6 @@ TEST_VM(metaspace, chunk_buddy_stuff) {

TEST_VM(metaspace, chunk_allocate_with_commit_limit) {

// This test does not make sense if commit-on-demand is off
if (Settings::new_chunks_are_fully_committed()) {
return;
}

const size_t granule_sz = Settings::commit_granule_words();
const size_t commit_limit = granule_sz * 3;
ChunkGtestContext context(commit_limit);
Expand Down
8 changes: 2 additions & 6 deletions test/hotspot/gtest/metaspace/test_metachunklist.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -151,10 +151,6 @@ TEST_VM(metaspace, freechunklist) {
// the retrieval-by-minimally-committed-words function.
TEST_VM(metaspace, freechunklist_retrieval) {

if (Settings::new_chunks_are_fully_committed()) {
return;
}

ChunkGtestContext context;
FreeChunkList fcl;
Metachunk* c = NULL;
Expand Down
46 changes: 22 additions & 24 deletions test/hotspot/gtest/metaspace/test_metaspacearena.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020 SAP SE. All rights reserved.
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2023 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -118,11 +118,7 @@ class MetaspaceArenaTestHelper {
size_t used_words_after = _used_words_counter.get();
size_t committed_words_after = limiter().committed_words();
ASSERT_0(used_words_after);
if (Settings::uncommit_free_chunks()) {
ASSERT_LE(committed_words_after, committed_words_before);
} else {
ASSERT_EQ(committed_words_after, committed_words_before);
}
ASSERT_LE(committed_words_after, committed_words_before);
}
}

Expand Down Expand Up @@ -177,12 +173,7 @@ class MetaspaceArenaTestHelper {

if (p == NULL) {
// Allocation failed.
if (Settings::new_chunks_are_fully_committed()) {
ASSERT_LT(possible_expansion, MAX_CHUNK_WORD_SIZE);
} else {
ASSERT_LT(possible_expansion, word_size);
}

ASSERT_LT(possible_expansion, word_size);
ASSERT_EQ(used, used2);
ASSERT_EQ(committed, committed2);
ASSERT_EQ(capacity, capacity2);
Expand Down Expand Up @@ -457,10 +448,6 @@ TEST_VM(metaspace, MetaspaceArena_deallocate) {

static void test_recover_from_commit_limit_hit() {

if (Settings::new_chunks_are_fully_committed()) {
return; // This would throw off the commit counting in this test.
}

// Test:
// - Multiple MetaspaceArena allocate (operating under the same commit limiter).
// - One, while attempting to commit parts of its current chunk on demand,
Expand Down Expand Up @@ -565,12 +552,23 @@ static void test_controlled_growth(Metaspace::MetaspaceType type, bool is_class,

ASSERT_EQ(capacity, expected_starting_capacity);

if (!(Settings::new_chunks_are_fully_committed() && type == Metaspace::BootMetaspaceType)) {
// Initial commit charge for the whole context should be one granule
ASSERT_EQ(context.committed_words(), Settings::commit_granule_words());
// Initial commit number for the arena should be less since - apart from boot loader - no
// space type has large initial chunks.
ASSERT_LE(committed, Settings::commit_granule_words());
// What happens when we allocate, commit wise:
// Arena allocates from current chunk, committing needed memory from the chunk on demand.
// The chunk asks the underlying vsnode to commit the area it is located in. Since the
// chunk may be smaller than one commit granule, this may result in surrounding memory
// also getting committed.
// In reality we will commit in granule granularity, but arena can only know what its first
// chunk did commit. So what it thinks was committed depends on the size of its first chunk,
// which depends on ArenaGrowthPolicy.
{
const chunklevel_t expected_level_for_first_chunk =
ArenaGrowthPolicy::policy_for_space_type(type, is_class)->get_level_at_step(0);
const size_t what_arena_should_think_was_committed =
MIN2(Settings::commit_granule_words(), word_size_for_level(expected_level_for_first_chunk));
const size_t what_should_really_be_committed = Settings::commit_granule_words();

ASSERT_EQ(committed, what_arena_should_think_was_committed);
ASSERT_EQ(context.committed_words(), what_should_really_be_committed);
}

///// subsequent allocations //
Expand Down Expand Up @@ -615,7 +613,7 @@ static void test_controlled_growth(Metaspace::MetaspaceType type, bool is_class,
ASSERT_GE(committed2, used2);
ASSERT_GE(committed2, committed);
const size_t committed_jump = committed2 - committed;
if (committed_jump > 0 && !Settings::new_chunks_are_fully_committed()) {
if (committed_jump > 0) {
ASSERT_LE(committed_jump, Settings::commit_granule_words());
}
committed = committed2;
Expand Down

1 comment on commit 519229d

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.