Path: blob/master/src/hotspot/share/memory/metaspace/metaspaceArena.hpp
40957 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*/2425#ifndef SHARE_MEMORY_METASPACE_METASPACEARENA_HPP26#define SHARE_MEMORY_METASPACE_METASPACEARENA_HPP2728#include "memory/allocation.hpp"29#include "memory/metaspace.hpp"30#include "memory/metaspace/chunkManager.hpp"31#include "memory/metaspace/counters.hpp"32#include "memory/metaspace/metachunk.hpp"33#include "memory/metaspace/metachunkList.hpp"34#include "memory/metaspace/metaspaceCommon.hpp"3536class outputStream;37class Mutex;3839namespace metaspace {4041class ArenaGrowthPolicy;42class FreeBlocks;4344struct ArenaStats;4546// The MetaspaceArena is a growable metaspace memory pool belonging to a CLD;47// internally it consists of a list of metaspace chunks, of which the head chunk48// is the current chunk from which we allocate via pointer bump.49//50// +---------------+51// | Arena |52// +---------------+53// |54// | _chunks commit top55// | v56// +----------+ +----------+ +----------+ +----------+57// | retired | ---> | retired | ---> | retired | ---> | current |58// | chunk | | chunk | | chunk | | chunk |59// +----------+ +----------+ +----------+ +----------+60// ^61// used top62//63// +------------+64// | FreeBlocks | --> O -> O -> O -> O65// +------------+66//67//6869// When the current chunk is used up, MetaspaceArena requestes a new chunk from70// the associated ChunkManager.71//72// MetaspaceArena also keeps a FreeBlocks structure to manage memory blocks which73// had been deallocated prematurely.74//7576class MetaspaceArena : public CHeapObj<mtClass> {7778// Reference to an outside lock to use for synchronizing access to this arena.79// This lock is normally owned by the CLD which owns the ClassLoaderMetaspace which80// owns this arena.81// Todo: This should be changed. Either the CLD should synchronize access to the82// CLMS and its arenas itself, or the arena should have an own lock. The latter83// would allow for more fine granular locking since it would allow access to84// both class- and non-class arena in the CLMS independently.85Mutex* const _lock;8687// Reference to the chunk manager to allocate chunks from.88ChunkManager* const _chunk_manager;8990// Reference to the growth policy to use.91const ArenaGrowthPolicy* const _growth_policy;9293// List of chunks. Head of the list is the current chunk.94MetachunkList _chunks;9596// Structure to take care of leftover/deallocated space in used chunks.97// Owned by the Arena. Gets allocated on demand only.98FreeBlocks* _fbl;99100Metachunk* current_chunk() { return _chunks.first(); }101const Metachunk* current_chunk() const { return _chunks.first(); }102103// Reference to an outside counter to keep track of used space.104SizeAtomicCounter* const _total_used_words_counter;105106// A name for purely debugging/logging purposes.107const char* const _name;108109Mutex* lock() const { return _lock; }110ChunkManager* chunk_manager() const { return _chunk_manager; }111112// free block list113FreeBlocks* fbl() const { return _fbl; }114void add_allocation_to_fbl(MetaWord* p, size_t word_size);115116// Given a chunk, add its remaining free committed space to the free block list.117void salvage_chunk(Metachunk* c);118119// Allocate a new chunk from the underlying chunk manager able to hold at least120// requested word size.121Metachunk* allocate_new_chunk(size_t requested_word_size);122123// Returns the level of the next chunk to be added, acc to growth policy.124chunklevel_t next_chunk_level() const;125126// Attempt to enlarge the current chunk to make it large enough to hold at least127// requested_word_size additional words.128//129// On success, true is returned, false otherwise.130bool attempt_enlarge_current_chunk(size_t requested_word_size);131132// Prematurely returns a metaspace allocation to the _block_freelists133// because it is not needed anymore (requires CLD lock to be active).134void deallocate_locked(MetaWord* p, size_t word_size);135136// Returns true if the area indicated by pointer and size have actually been allocated137// from this arena.138DEBUG_ONLY(bool is_valid_area(MetaWord* p, size_t word_size) const;)139140public:141142MetaspaceArena(ChunkManager* chunk_manager, const ArenaGrowthPolicy* growth_policy,143Mutex* lock, SizeAtomicCounter* total_used_words_counter,144const char* name);145146~MetaspaceArena();147148// Allocate memory from Metaspace.149// 1) Attempt to allocate from the dictionary of deallocated blocks.150// 2) Attempt to allocate from the current chunk.151// 3) Attempt to enlarge the current chunk in place if it is too small.152// 4) Attempt to get a new chunk and allocate from that chunk.153// At any point, if we hit a commit limit, we return NULL.154MetaWord* allocate(size_t word_size);155156// Prematurely returns a metaspace allocation to the _block_freelists because it is not157// needed anymore.158void deallocate(MetaWord* p, size_t word_size);159160// Update statistics. This walks all in-use chunks.161void add_to_statistics(ArenaStats* out) const;162163// Convenience method to get the most important usage statistics.164// For deeper analysis use add_to_statistics().165void usage_numbers(size_t* p_used_words, size_t* p_committed_words, size_t* p_capacity_words) const;166167DEBUG_ONLY(void verify() const;)168DEBUG_ONLY(void verify_locked() const;)169DEBUG_ONLY(void verify_allocation_guards() const;)170171void print_on(outputStream* st) const;172void print_on_locked(outputStream* st) const;173174};175176} // namespace metaspace177178#endif // SHARE_MEMORY_METASPACE_METASPACEARENA_HPP179180181182