Path: blob/master/src/hotspot/share/memory/metaspace/chunkManager.hpp
40957 views
/*1* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2018, 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*/2425#ifndef SHARE_MEMORY_METASPACE_CHUNKMANAGER_HPP26#define SHARE_MEMORY_METASPACE_CHUNKMANAGER_HPP2728#include "memory/allocation.hpp"29#include "memory/metaspace/chunklevel.hpp"30#include "memory/metaspace/counters.hpp"31#include "memory/metaspace/freeChunkList.hpp"32#include "memory/metaspace/metachunk.hpp"3334namespace metaspace {3536class VirtualSpaceList;37struct ChunkManagerStats;3839// ChunkManager has a somewhat central role.4041// Arenas request chunks from it and, on death, return chunks back to it.42// It keeps freelists for chunks, one per chunk level, sorted by chunk43// commit state.44// To feed the freelists, it allocates root chunks from the associated45// VirtualSpace below it.46//47// ChunkManager directs splitting chunks, if a chunk request cannot be48// fulfilled directly. It also takes care of merging when chunks are49// returned to it, before they are added to the freelist.50//51// The freelists are double linked double headed; fully committed chunks52// are added to the front, others to the back.53//54// Level55// +--------------------+ +--------------------+56// 0 +----| free root chunk |---| free root chunk |---...57// | +--------------------+ +--------------------+58// |59// | +----------+ +----------+60// 1 +----| |---| |---...61// | +----------+ +----------+62// |63// .64// .65// .66//67// | +-+ +-+68// 12 +----| |---| |---...69// +-+ +-+7071class ChunkManager : public CHeapObj<mtMetaspace> {7273// A chunk manager is connected to a virtual space list which is used74// to allocate new root chunks when no free chunks are found.75VirtualSpaceList* const _vslist;7677// Name78const char* const _name;7980// Freelists81FreeChunkListVector _chunks;8283// Returns true if this manager contains the given chunk. Slow (walks free lists) and84// only needed for verifications.85DEBUG_ONLY(bool contains_chunk(Metachunk* c) const;)8687// Given a chunk, split it into a target chunk of a smaller size (target level)88// at least one, possible more splinter chunks. Splinter chunks are added to the89// freelist.90// The original chunk must be outside of the freelist and its state must be free.91// The resulting target chunk will be located at the same address as the original92// chunk, but it will of course be smaller (of a higher level).93// The committed areas within the original chunk carry over to the resulting94// chunks.95void split_chunk_and_add_splinters(Metachunk* c, chunklevel_t target_level);9697// See get_chunk(s,s,s)98Metachunk* get_chunk_locked(size_t preferred_word_size, size_t min_word_size, size_t min_committed_words);99100// Uncommit all chunks equal or below the given level.101void uncommit_free_chunks(chunklevel_t max_level);102103// Return a single chunk to the freelist without doing any merging, and adjust accounting.104void return_chunk_simple_locked(Metachunk* c);105106// See return_chunk().107void return_chunk_locked(Metachunk* c);108109// Calculates the total number of committed words over all chunks. Walks chunks.110size_t calc_committed_word_size_locked() const;111112public:113114// Creates a chunk manager with a given name (which is for debug purposes only)115// and an associated space list which will be used to request new chunks from116// (see get_chunk())117ChunkManager(const char* name, VirtualSpaceList* space_list);118119// On success, returns a chunk of level of <preferred_level>, but at most <max_level>.120// The first <min_committed_words> of the chunk are guaranteed to be committed.121// On error, will return NULL.122//123// This function may fail for two reasons:124// - Either we are unable to reserve space for a new chunk (if the underlying VirtualSpaceList125// is non-expandable but needs expanding - aka out of compressed class space).126// - Or, if the necessary space cannot be committed because we hit a commit limit.127// This may be either the GC threshold or MaxMetaspaceSize.128Metachunk* get_chunk(chunklevel_t preferred_level, chunklevel_t max_level, size_t min_committed_words);129130// Convenience function - get a chunk of a given level, uncommitted.131Metachunk* get_chunk(chunklevel_t lvl) { return get_chunk(lvl, lvl, 0); }132133// Return a single chunk to the ChunkManager and adjust accounting. May merge chunk134// with neighbors.135// Happens after a Classloader was unloaded and releases its metaspace chunks.136// !! Notes:137// 1) After this method returns, c may not be valid anymore. ** Do not access c after this function returns **.138// 2) This function will not remove c from its current chunk list. This has to be done by the caller prior to139// calling this method.140void return_chunk(Metachunk* c);141142// Given a chunk c, which must be "in use" and must not be a root chunk, attempt to143// enlarge it in place by claiming its trailing buddy.144//145// This will only work if c is the leader of the buddy pair and the trailing buddy is free.146//147// If successful, the follower chunk will be removed from the freelists, the leader chunk c will148// double in size (level decreased by one).149//150// On success, true is returned, false otherwise.151bool attempt_enlarge_chunk(Metachunk* c);152153// Attempt to reclaim free areas in metaspace wholesale:154// - first, attempt to purge nodes of the backing virtual space list: nodes which are completely155// unused get unmapped and deleted completely.156// - second, it will uncommit free chunks depending on commit granule size.157void purge();158159// Run verifications. slow=true: verify chunk-internal integrity too.160DEBUG_ONLY(void verify() const;)161DEBUG_ONLY(void verify_locked() const;)162163// Returns the name of this chunk manager.164const char* name() const { return _name; }165166// Returns total number of chunks167int total_num_chunks() const { return _chunks.num_chunks(); }168169// Returns number of words in all free chunks (regardless of commit state).170size_t total_word_size() const { return _chunks.word_size(); }171172// Calculates the total number of committed words over all chunks. Walks chunks.173size_t calc_committed_word_size() const;174175// Update statistics.176void add_to_statistics(ChunkManagerStats* out) const;177178void print_on(outputStream* st) const;179void print_on_locked(outputStream* st) const;180181// Convenience methods to return the global class-space chunkmanager182// and non-class chunkmanager, respectively.183static ChunkManager* chunkmanager_class();184static ChunkManager* chunkmanager_nonclass();185186};187188} // namespace metaspace189190#endif // SHARE_MEMORY_METASPACE_CHUNKMANAGER_HPP191192193