# HG changeset patch # User stuefe # Date 1569408057 -7200 # Node ID 78b2e8f46dd44ff80b76a77fcd92cb905980d399 # Parent 6e61beb13680e9a40d5419883c5ebd9990acad96 add experimental option to cluster micro clds. diff -r 6e61beb13680 -r 78b2e8f46dd4 src/hotspot/share/memory/metaspace.cpp --- a/src/hotspot/share/memory/metaspace.cpp Thu Sep 19 16:28:40 2019 +0200 +++ b/src/hotspot/share/memory/metaspace.cpp Wed Sep 25 12:40:57 2019 +0200 @@ -716,6 +716,10 @@ ChunkManager* cm = new ChunkManager("class space chunk manager", vsl); ChunkManager::set_chunkmanager_class(cm); + if (metaspace::Settings::separate_micro_cld_allocations()) { + ChunkManager* cm2 = new ChunkManager("microcld class space chunk manager", vsl); + ChunkManager::set_chunkmanager_microclds_class(cm2); + } } @@ -737,17 +741,7 @@ void Metaspace::ergo_initialize() { // Must happen before using any setting from Settings::--- - metaspace::Settings::strategy_t strat = metaspace::Settings::strategy_balanced_reclaim; - if (strcmp(MetaspaceReclaimStrategy, "balanced") == 0) { - strat = metaspace::Settings::strategy_balanced_reclaim; - } else if (strcmp(MetaspaceReclaimStrategy, "aggressive") == 0) { - strat = metaspace::Settings::strategy_aggressive_reclaim; - } else if (strcmp(MetaspaceReclaimStrategy, "none") == 0) { - strat = metaspace::Settings::strategy_no_reclaim; - } else { - vm_exit_during_initialization("Invalid value for MetaspaceReclaimStrategy: \"%s\".", MetaspaceReclaimStrategy); - } - metaspace::Settings::initialize(strat); + metaspace::Settings::ergo_initialize(); if (DumpSharedSpaces) { // Using large pages when dumping the shared archive is currently not implemented. @@ -840,11 +834,16 @@ } // Initialize non-class virtual space list, and its chunk manager: - VirtualSpaceList* vsl = new VirtualSpaceList("Non-Class VirtualSpaceList", CommitLimiter::globalLimiter()); + VirtualSpaceList* vsl = new VirtualSpaceList("non-class virtualspacelist", CommitLimiter::globalLimiter()); VirtualSpaceList::set_vslist_nonclass(vsl); - ChunkManager* cm = new ChunkManager("Non-Class ChunkManager", vsl); + ChunkManager* cm = new ChunkManager("non-class chunkmanager", vsl); ChunkManager::set_chunkmanager_nonclass(cm); + if (metaspace::Settings::separate_micro_cld_allocations()) { + ChunkManager* cm2 = new ChunkManager("microcld non-class chunk manager", vsl); + ChunkManager::set_chunkmanager_microclds_nonclass(cm2); + } + _tracer = new MetaspaceTracer(); _initialized = true; diff -r 6e61beb13680 -r 78b2e8f46dd4 src/hotspot/share/memory/metaspace/chunkManager.cpp --- a/src/hotspot/share/memory/metaspace/chunkManager.cpp Thu Sep 19 16:28:40 2019 +0200 +++ b/src/hotspot/share/memory/metaspace/chunkManager.cpp Wed Sep 25 12:40:57 2019 +0200 @@ -425,6 +425,19 @@ _chunkmanager_nonclass = cm; } +ChunkManager* ChunkManager::_chunkmanager_microclds_class = NULL; +ChunkManager* ChunkManager::_chunkmanager_microclds_nonclass = NULL; + +void ChunkManager::set_chunkmanager_microclds_class(ChunkManager* cm) { + assert(_chunkmanager_microclds_class == NULL, "Sanity"); + _chunkmanager_microclds_class = cm; +} + +void ChunkManager::set_chunkmanager_microclds_nonclass(ChunkManager* cm) { + assert(_chunkmanager_microclds_nonclass == NULL, "Sanity"); + _chunkmanager_microclds_nonclass = cm; +} + // Update statistics. void ChunkManager::add_to_statistics(cm_stats_t* out) const { diff -r 6e61beb13680 -r 78b2e8f46dd4 src/hotspot/share/memory/metaspace/chunkManager.hpp --- a/src/hotspot/share/memory/metaspace/chunkManager.hpp Thu Sep 19 16:28:40 2019 +0200 +++ b/src/hotspot/share/memory/metaspace/chunkManager.hpp Wed Sep 25 12:40:57 2019 +0200 @@ -156,6 +156,21 @@ static void set_chunkmanager_class(ChunkManager* cm); static void set_chunkmanager_nonclass(ChunkManager* cm); + // If micro clds are kept separate... +private: + + static ChunkManager* _chunkmanager_microclds_class; + static ChunkManager* _chunkmanager_microclds_nonclass; + +public: + + static ChunkManager* chunkmanager_microclds_class() { return _chunkmanager_microclds_class; } + static ChunkManager* chunkmanager_microclds_nonclass() { return _chunkmanager_microclds_nonclass; } + + static void set_chunkmanager_microclds_class(ChunkManager* cm); + static void set_chunkmanager_microclds_nonclass(ChunkManager* cm); + + }; } // namespace metaspace diff -r 6e61beb13680 -r 78b2e8f46dd4 src/hotspot/share/memory/metaspace/classLoaderMetaspace.cpp --- a/src/hotspot/share/memory/metaspace/classLoaderMetaspace.cpp Thu Sep 19 16:28:40 2019 +0200 +++ b/src/hotspot/share/memory/metaspace/classLoaderMetaspace.cpp Wed Sep 25 12:40:57 2019 +0200 @@ -42,14 +42,17 @@ namespace metaspace { static bool use_class_space(bool is_class) { - if (Metaspace::using_class_space()) { - if (is_class) { - return true; - } + if (Metaspace::using_class_space() && is_class) { + return true; } return false; } +static bool is_micro_cld(MetaspaceType space_type) { + return space_type == metaspace::UnsafeAnonymousMetaspaceType || + space_type == metaspace::ReflectionMetaspaceType; +} + static bool use_class_space(MetadataType mdType) { return use_class_space(is_class(mdType)); } @@ -60,9 +63,14 @@ , _non_class_space_manager(NULL) , _class_space_manager(NULL) { + ChunkManager* const non_class_cm = + is_micro_cld(_space_type) && Settings::separate_micro_cld_allocations() ? + ChunkManager::chunkmanager_microclds_nonclass() : + ChunkManager::chunkmanager_nonclass(); + // Initialize non-class spacemanager _non_class_space_manager = new SpaceManager( - ChunkManager::chunkmanager_nonclass(), + non_class_cm, ChunkAllocSequence::alloc_sequence_by_space_type(space_type, false), lock, RunningCounters::used_nonclass_counter(), @@ -70,8 +78,12 @@ // If needed, initialize class spacemanager if (Metaspace::using_class_space()) { + ChunkManager* const class_cm = + is_micro_cld(_space_type) && Settings::separate_micro_cld_allocations() ? + ChunkManager::chunkmanager_microclds_class() : + ChunkManager::chunkmanager_class(); _class_space_manager = new SpaceManager( - ChunkManager::chunkmanager_class(), + class_cm, ChunkAllocSequence::alloc_sequence_by_space_type(space_type, true), lock, RunningCounters::used_class_counter(), diff -r 6e61beb13680 -r 78b2e8f46dd4 src/hotspot/share/memory/metaspace/settings.cpp --- a/src/hotspot/share/memory/metaspace/settings.cpp Thu Sep 19 16:28:40 2019 +0200 +++ b/src/hotspot/share/memory/metaspace/settings.cpp Wed Sep 25 12:40:57 2019 +0200 @@ -54,10 +54,11 @@ size_t Settings::_uncommit_on_purge_min_word_size = 0; -void Settings::initialize(strategy_t strat) { +bool Settings::_separate_micro_cld_allocations = false; - switch (strat) { - case strategy_no_reclaim: +void Settings::ergo_initialize() { + + if (strcmp(MetaspaceReclaimStrategy, "none") == 0) { log_info(metaspace)("Initialized with strategy: no reclaim."); @@ -75,9 +76,7 @@ _uncommit_on_purge = false; _uncommit_on_purge_min_word_size = 3; // does not matter; should not be used resp. assert when used. - break; - - case strategy_aggressive_reclaim: + } else if (strcmp(MetaspaceReclaimStrategy, "aggressive") == 0) { log_info(metaspace)("Initialized with strategy: aggressive reclaim."); @@ -100,9 +99,7 @@ _uncommit_on_purge = true; _uncommit_on_purge_min_word_size = _commit_granule_words; // does not matter; should not be used resp. assert when used. - break; - - case strategy_balanced_reclaim: + } else if (strcmp(MetaspaceReclaimStrategy, "balanced") == 0) { log_info(metaspace)("Initialized with strategy: balanced reclaim."); @@ -123,7 +120,9 @@ _uncommit_on_purge = true; _uncommit_on_purge_min_word_size = _commit_granule_words; - break; + } else { + + vm_exit_during_initialization("Invalid value for MetaspaceReclaimStrategy: \"%s\".", MetaspaceReclaimStrategy); } @@ -132,6 +131,8 @@ _enlarge_chunks_in_place = true; _enlarge_chunks_in_place_max_word_size = 256 * K; + // Optionally, we can shepherd micro cld metaspace allocs to an own root chunk. + _separate_micro_cld_allocations = MetaspaceSeparateMicroCLDs; // Sanity checks. guarantee(commit_granule_words() <= chklvl::MAX_CHUNK_WORD_SIZE, "Too large granule size"); diff -r 6e61beb13680 -r 78b2e8f46dd4 src/hotspot/share/memory/metaspace/settings.hpp --- a/src/hotspot/share/memory/metaspace/settings.hpp Thu Sep 19 16:28:40 2019 +0200 +++ b/src/hotspot/share/memory/metaspace/settings.hpp Wed Sep 25 12:40:57 2019 +0200 @@ -84,6 +84,10 @@ // Must be a multiple of and not smaller than commit granularity. static size_t _uncommit_on_purge_min_word_size; + // If true, allocations from micro-clds (CLDs which only load one class, e.g. hidden classes or + // reflection loaders) are shepherded into an own root chunk. + static bool _separate_micro_cld_allocations; + public: static size_t commit_granule_bytes() { return _commit_granule_bytes; } @@ -99,25 +103,9 @@ static bool delete_nodes_on_purge() { return _delete_nodes_on_purge; } static bool uncommit_on_purge() { return _uncommit_on_purge; } static size_t uncommit_on_purge_min_word_size() { return _uncommit_on_purge_min_word_size; } - - // Describes a group of settings - enum strategy_t { - - // Do not uncommit chunks. New chunks are completely committed thru from the start. - strategy_no_reclaim, + static bool separate_micro_cld_allocations() { return _separate_micro_cld_allocations; } - // Uncommit very aggressively. - // - a rather small granule size of 16K - // - New chunks are committed for one granule size - // - returned chunks are uncommitted whenever possible - strategy_aggressive_reclaim, - - // Uncommit, but try to strike a balance with CPU load - strategy_balanced_reclaim - - }; - - static void initialize(strategy_t theme); + static void ergo_initialize(); static void print_on(outputStream* st); diff -r 6e61beb13680 -r 78b2e8f46dd4 src/hotspot/share/runtime/globals.hpp --- a/src/hotspot/share/runtime/globals.hpp Thu Sep 19 16:28:40 2019 +0200 +++ b/src/hotspot/share/runtime/globals.hpp Wed Sep 25 12:40:57 2019 +0200 @@ -1616,6 +1616,9 @@ product(ccstr, MetaspaceReclaimStrategy, "balanced", \ "options: balanced, aggressive, none") \ \ + product(bool, MetaspaceSeparateMicroCLDs, false, \ + "Micro CLDs are separated.") \ + \ manageable(uintx, MinHeapFreeRatio, 40, \ "The minimum percentage of heap free after GC to avoid expansion."\ " For most GCs this applies to the old generation. In G1 and" \