< prev index next >
src/hotspot/share/memory/metaspace.hpp
Print this page
rev 60538 : imported patch jep387-all.patch
*** 26,102 ****
#include "memory/allocation.hpp"
#include "memory/memRegion.hpp"
#include "memory/metaspaceChunkFreeListSummary.hpp"
#include "memory/virtualspace.hpp"
- #include "memory/metaspace/metaspaceSizesSnapshot.hpp"
#include "runtime/globals.hpp"
#include "utilities/exceptions.hpp"
!
! // Metaspace
! //
! // Metaspaces are Arenas for the VM's metadata.
! // They are allocated one per class loader object, and one for the null
! // bootstrap class loader
! //
! // block X ---+ +-------------------+
! // | | Virtualspace |
! // | | |
! // | | |
! // | |-------------------|
! // | || Chunk |
! // | || |
! // | ||---------- |
! // +------>||| block 0 | |
! // ||---------- |
! // ||| block 1 | |
! // ||---------- |
! // || |
! // |-------------------|
! // | |
! // | |
! // +-------------------+
! //
class ClassLoaderData;
class MetaspaceTracer;
class Mutex;
class outputStream;
- class CollectedHeap;
-
namespace metaspace {
! class ChunkManager;
! class ClassLoaderMetaspaceStatistics;
! class Metablock;
! class Metachunk;
! class PrintCLDMetaspaceInfoClosure;
! class SpaceManager;
! class VirtualSpaceList;
! class VirtualSpaceNode;
}
! // Metaspaces each have a SpaceManager and allocations
! // are done by the SpaceManager. Allocations are done
! // out of the current Metachunk. When the current Metachunk
! // is exhausted, the SpaceManager gets a new one from
! // the current VirtualSpace. When the VirtualSpace is exhausted
! // the SpaceManager gets a new one. The SpaceManager
! // also manages freelists of available Chunks.
! //
! // Currently the space manager maintains the list of
! // virtual spaces and the list of chunks in use. Its
! // allocate() method returns a block for use as a
! // quantum of metadata.
// Namespace for important central static functions
// (auxiliary stuff goes into MetaspaceUtils)
class Metaspace : public AllStatic {
friend class MetaspaceShared;
! public:
enum MetadataType {
ClassType,
NonClassType,
MetadataTypeCount
};
--- 26,60 ----
#include "memory/allocation.hpp"
#include "memory/memRegion.hpp"
#include "memory/metaspaceChunkFreeListSummary.hpp"
#include "memory/virtualspace.hpp"
#include "runtime/globals.hpp"
#include "utilities/exceptions.hpp"
! #include "utilities/globalDefinitions.hpp"
class ClassLoaderData;
+ class MetaspaceShared;
class MetaspaceTracer;
class Mutex;
class outputStream;
namespace metaspace {
! class MetaspaceArena;
! class MetaspaceSizesSnapshot;
! struct clms_stats_t;
}
! ////////////////// Metaspace ///////////////////////
// Namespace for important central static functions
// (auxiliary stuff goes into MetaspaceUtils)
class Metaspace : public AllStatic {
friend class MetaspaceShared;
! public:
enum MetadataType {
ClassType,
NonClassType,
MetadataTypeCount
};
*** 107,169 ****
ClassMirrorHolderMetaspaceType = BootMetaspaceType + 1,
ReflectionMetaspaceType = ClassMirrorHolderMetaspaceType + 1,
MetaspaceTypeCount
};
! private:
!
! // Align up the word size to the allocation word size
! static size_t align_word_size_up(size_t);
!
! // Aligned size of the metaspace.
! static size_t _compressed_class_space_size;
!
! static size_t compressed_class_space_size() {
! return _compressed_class_space_size;
! }
!
! static void set_compressed_class_space_size(size_t size) {
! _compressed_class_space_size = size;
! }
!
! static size_t _first_chunk_word_size;
! static size_t _first_class_chunk_word_size;
- static size_t _commit_alignment;
- static size_t _reserve_alignment;
DEBUG_ONLY(static bool _frozen;)
- // Virtual Space lists for both classes and other metadata
- static metaspace::VirtualSpaceList* _space_list;
- static metaspace::VirtualSpaceList* _class_space_list;
-
- static metaspace::ChunkManager* _chunk_manager_metadata;
- static metaspace::ChunkManager* _chunk_manager_class;
-
static const MetaspaceTracer* _tracer;
static bool _initialized;
! public:
! static metaspace::VirtualSpaceList* space_list() { return _space_list; }
! static metaspace::VirtualSpaceList* class_space_list() { return _class_space_list; }
! static metaspace::VirtualSpaceList* get_space_list(MetadataType mdtype) {
! assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
! return mdtype == ClassType ? class_space_list() : space_list();
! }
!
! static metaspace::ChunkManager* chunk_manager_metadata() { return _chunk_manager_metadata; }
! static metaspace::ChunkManager* chunk_manager_class() { return _chunk_manager_class; }
! static metaspace::ChunkManager* get_chunk_manager(MetadataType mdtype) {
! assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
! return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata();
! }
!
! // convenience function
! static metaspace::ChunkManager* get_chunk_manager(bool is_class) {
! return is_class ? chunk_manager_class() : chunk_manager_metadata();
! }
static const MetaspaceTracer* tracer() { return _tracer; }
static void freeze() {
assert(DumpSharedSpaces, "sanity");
DEBUG_ONLY(_frozen = true;)
--- 65,83 ----
ClassMirrorHolderMetaspaceType = BootMetaspaceType + 1,
ReflectionMetaspaceType = ClassMirrorHolderMetaspaceType + 1,
MetaspaceTypeCount
};
! private:
DEBUG_ONLY(static bool _frozen;)
static const MetaspaceTracer* _tracer;
static bool _initialized;
! public:
static const MetaspaceTracer* tracer() { return _tracer; }
static void freeze() {
assert(DumpSharedSpaces, "sanity");
DEBUG_ONLY(_frozen = true;)
*** 186,447 ****
// Given a prereserved space, use that to set up the compressed class space list.
static void initialize_class_space(ReservedSpace rs);
// Returns true if class space has been setup (initialize_class_space).
! static bool class_space_is_initialized() { return _class_space_list != NULL; }
#endif
public:
static void ergo_initialize();
static void global_initialize();
static void post_initialize();
! static void verify_global_initialization();
!
! static size_t first_chunk_word_size() { return _first_chunk_word_size; }
! static size_t first_class_chunk_word_size() { return _first_class_chunk_word_size; }
! static size_t reserve_alignment() { return _reserve_alignment; }
! static size_t reserve_alignment_words() { return _reserve_alignment / BytesPerWord; }
! static size_t commit_alignment() { return _commit_alignment; }
! static size_t commit_alignment_words() { return _commit_alignment / BytesPerWord; }
static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
MetaspaceObj::Type type, TRAPS);
static bool contains(const void* ptr);
static bool contains_non_shared(const void* ptr);
// Free empty virtualspaces
- static void purge(MetadataType mdtype);
static void purge();
static void report_metadata_oome(ClassLoaderData* loader_data, size_t word_size,
! MetaspaceObj::Type type, MetadataType mdtype, TRAPS);
!
! static const char* metadata_type_name(Metaspace::MetadataType mdtype);
static void print_compressed_class_space(outputStream* st) NOT_LP64({});
// Return TRUE only if UseCompressedClassPointers is True.
static bool using_class_space() {
return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers);
}
! static bool is_class_space_allocation(MetadataType mdType) {
! return mdType == ClassType && using_class_space();
! }
!
! static bool initialized() { return _initialized; }
};
! // Manages the metaspace portion belonging to a class loader
class ClassLoaderMetaspace : public CHeapObj<mtClass> {
- friend class CollectedHeap; // For expand_and_allocate()
- friend class ZCollectedHeap; // For expand_and_allocate()
- friend class ShenandoahHeap; // For expand_and_allocate()
- friend class Metaspace;
- friend class MetaspaceUtils;
- friend class metaspace::PrintCLDMetaspaceInfoClosure;
- friend class VM_CollectForMetadataAllocation; // For expand_and_allocate()
! private:
!
! void initialize(Mutex* lock, Metaspace::MetaspaceType type);
!
! // Initialize the first chunk for a Metaspace. Used for
! // special cases such as the boot class loader, reflection
! // class loader and hidden class loader.
! void initialize_first_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype);
! metaspace::Metachunk* get_initialization_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype);
const Metaspace::MetaspaceType _space_type;
- Mutex* const _lock;
- metaspace::SpaceManager* _vsm;
- metaspace::SpaceManager* _class_vsm;
! metaspace::SpaceManager* vsm() const { return _vsm; }
! metaspace::SpaceManager* class_vsm() const { return _class_vsm; }
! metaspace::SpaceManager* get_space_manager(Metaspace::MetadataType mdtype) {
! assert(mdtype != Metaspace::MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
! return mdtype == Metaspace::ClassType ? class_vsm() : vsm();
! }
Mutex* lock() const { return _lock; }
! MetaWord* expand_and_allocate(size_t size, Metaspace::MetadataType mdtype);
!
! size_t class_chunk_size(size_t word_size);
! // Adds to the given statistic object. Must be locked with CLD metaspace lock.
! void add_to_statistics_locked(metaspace::ClassLoaderMetaspaceStatistics* out) const;
! Metaspace::MetaspaceType space_type() const { return _space_type; }
- public:
-
- ClassLoaderMetaspace(Mutex* lock, Metaspace::MetaspaceType type);
~ClassLoaderMetaspace();
! // Allocate space for metadata of type mdtype. This is space
! // within a Metachunk and is used by
! // allocate(ClassLoaderData*, size_t, bool, MetadataType, TRAPS)
! MetaWord* allocate(size_t word_size, Metaspace::MetadataType mdtype);
!
! size_t allocated_blocks_bytes() const;
! size_t allocated_chunks_bytes() const;
!
! void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
!
! void print_on(outputStream* st) const;
! // Debugging support
! void verify();
!
! // Adds to the given statistic object. Will lock with CLD metaspace lock.
! void add_to_statistics(metaspace::ClassLoaderMetaspaceStatistics* out) const;
!
! }; // ClassLoaderMetaspace
!
! class MetaspaceUtils : AllStatic {
! // Spacemanager updates running counters.
! friend class metaspace::SpaceManager;
! // Special access for error reporting (checks without locks).
! friend class oopDesc;
! friend class Klass;
!
! // Running counters for statistics concerning in-use chunks.
! // Note: capacity = used + free + waste + overhead. Note that we do not
! // count free and waste. Their sum can be deduces from the three other values.
! // For more details, one should call print_report() from within a safe point.
! static size_t _capacity_words [Metaspace:: MetadataTypeCount];
! static size_t _overhead_words [Metaspace:: MetadataTypeCount];
! static volatile size_t _used_words [Metaspace:: MetadataTypeCount];
!
! // Atomically decrement or increment in-use statistic counters
! static void dec_capacity(Metaspace::MetadataType mdtype, size_t words);
! static void inc_capacity(Metaspace::MetadataType mdtype, size_t words);
! static void dec_used(Metaspace::MetadataType mdtype, size_t words);
! static void inc_used(Metaspace::MetadataType mdtype, size_t words);
! static void dec_overhead(Metaspace::MetadataType mdtype, size_t words);
! static void inc_overhead(Metaspace::MetadataType mdtype, size_t words);
!
!
! // Getters for the in-use counters.
! static size_t capacity_words(Metaspace::MetadataType mdtype) { return _capacity_words[mdtype]; }
! static size_t used_words(Metaspace::MetadataType mdtype) { return _used_words[mdtype]; }
! static size_t overhead_words(Metaspace::MetadataType mdtype) { return _overhead_words[mdtype]; }
! static size_t free_chunks_total_words(Metaspace::MetadataType mdtype);
! // Helper for print_xx_report.
! static void print_vs(outputStream* out, size_t scale);
! public:
! // Collect used metaspace statistics. This involves walking the CLDG. The resulting
! // output will be the accumulated values for all live metaspaces.
! // Note: method does not do any locking.
! static void collect_statistics(metaspace::ClassLoaderMetaspaceStatistics* out);
!
! // Used by MetaspaceCounters
! static size_t free_chunks_total_words();
! static size_t free_chunks_total_bytes();
! static size_t free_chunks_total_bytes(Metaspace::MetadataType mdtype);
!
! static size_t capacity_words() {
! return capacity_words(Metaspace::NonClassType) +
! capacity_words(Metaspace::ClassType);
! }
! static size_t capacity_bytes(Metaspace::MetadataType mdtype) {
! return capacity_words(mdtype) * BytesPerWord;
! }
! static size_t capacity_bytes() {
! return capacity_words() * BytesPerWord;
! }
! static size_t used_words() {
! return used_words(Metaspace::NonClassType) +
! used_words(Metaspace::ClassType);
! }
! static size_t used_bytes(Metaspace::MetadataType mdtype) {
! return used_words(mdtype) * BytesPerWord;
! }
! static size_t used_bytes() {
! return used_words() * BytesPerWord;
! }
- // Space committed but yet unclaimed by any class loader.
- static size_t free_in_vs_bytes();
- static size_t free_in_vs_bytes(Metaspace::MetadataType mdtype);
-
- static size_t reserved_bytes(Metaspace::MetadataType mdtype);
- static size_t reserved_bytes() {
- return reserved_bytes(Metaspace::ClassType) +
- reserved_bytes(Metaspace::NonClassType);
- }
! static size_t committed_bytes(Metaspace::MetadataType mdtype);
! static size_t committed_bytes() {
! return committed_bytes(Metaspace::ClassType) +
! committed_bytes(Metaspace::NonClassType);
! }
! static size_t min_chunk_size_words();
! // Flags for print_report().
! enum ReportFlag {
! // Show usage by class loader.
! rf_show_loaders = (1 << 0),
! // Breaks report down by chunk type (small, medium, ...).
! rf_break_down_by_chunktype = (1 << 1),
! // Breaks report down by space type (hidden, reflection, ...).
! rf_break_down_by_spacetype = (1 << 2),
! // Print details about the underlying virtual spaces.
! rf_show_vslist = (1 << 3),
! // Print metaspace map.
! rf_show_vsmap = (1 << 4),
! // If show_loaders: show loaded classes for each loader.
! rf_show_classes = (1 << 5)
};
! // This will print out a basic metaspace usage report but
! // unlike print_report() is guaranteed not to lock or to walk the CLDG.
! static void print_basic_report(outputStream* st, size_t scale);
!
! // Prints a report about the current metaspace state.
! // Optional parts can be enabled via flags.
! // Function will walk the CLDG and will lock the expand lock; if that is not
! // convenient, use print_basic_report() instead.
! static void print_report(outputStream* out, size_t scale = 0, int flags = 0);
!
! static bool has_chunk_free_list(Metaspace::MetadataType mdtype);
! static MetaspaceChunkFreeListSummary chunk_free_list_summary(Metaspace::MetadataType mdtype);
!
! // Log change in used metadata.
! static void print_metaspace_change(const metaspace::MetaspaceSizesSnapshot& pre_meta_values);
! static void print_on(outputStream * out);
!
! // Prints an ASCII representation of the given space.
! static void print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype);
!
! static void dump(outputStream* out);
! static void verify_free_chunks();
! // Check internal counters (capacity, used).
! static void verify_metrics();
};
! // Metaspace are deallocated when their class loader are GC'ed.
! // This class implements a policy for inducing GC's to recover
! // Metaspaces.
!
! class MetaspaceGC : AllStatic {
// The current high-water-mark for inducing a GC.
// When committed memory of all metaspaces reaches this value,
// a GC is induced and the value is increased. Size is in bytes.
static volatile size_t _capacity_until_GC;
--- 100,261 ----
// Given a prereserved space, use that to set up the compressed class space list.
static void initialize_class_space(ReservedSpace rs);
// Returns true if class space has been setup (initialize_class_space).
! static bool class_space_is_initialized();
#endif
public:
static void ergo_initialize();
static void global_initialize();
static void post_initialize();
! // Alignment, in bytes, of metaspace mappings
! static size_t reserve_alignment() { return reserve_alignment_words() * BytesPerWord; }
! // Alignment, in words, of metaspace mappings
! static size_t reserve_alignment_words();
!
! // The granularity at which Metaspace is committed and uncommitted.
! // (Todo: Why does this have to be exposed?)
! static size_t commit_alignment() { return commit_alignment_words() * BytesPerWord; }
! static size_t commit_alignment_words();
! // The largest possible single allocation
! static size_t max_allocation_word_size();
static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
MetaspaceObj::Type type, TRAPS);
static bool contains(const void* ptr);
static bool contains_non_shared(const void* ptr);
// Free empty virtualspaces
static void purge();
static void report_metadata_oome(ClassLoaderData* loader_data, size_t word_size,
! MetaspaceObj::Type type, Metaspace::MetadataType mdtype, TRAPS);
static void print_compressed_class_space(outputStream* st) NOT_LP64({});
// Return TRUE only if UseCompressedClassPointers is True.
static bool using_class_space() {
return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers);
}
! static bool initialized();
};
! // ClassLoaderMetaspace is an inbetween-object between a CLD and its MetaspaceArena(s).
! //
! // A CLD owns one MetaspaceArena if compressed class space is off, two if its one
! // (one for allocations of Klass* structures from class space, one for the rest from
! // non-class space).
! //
! // ClassLoaderMetaspace only exists to hide this logic from upper layers:
! //
! // +------+ +----------------------+ +-------------------+
! // | CLD | ---> | ClassLoaderMetaspace | ----> | (non class) Arena |
! // +------+ +----------------------+ | +-------------------+ allocation top
! // | | v
! // | + chunk -- chunk ... -- chunk
! // |
! // | +-------------------+
! // +--> | (class) Arena |
! // +-------------------+
! // |
! // + chunk ... chunk
! // ^
! // alloc top
! //
class ClassLoaderMetaspace : public CHeapObj<mtClass> {
! // A reference to an outside lock, held by the CLD.
! Mutex* const _lock;
const Metaspace::MetaspaceType _space_type;
! // Arena for allocations from non-class metaspace
! // (resp. for all allocations if -XX:-UseCompressedClassPointers).
! metaspace::MetaspaceArena* _non_class_space_arena;
!
! // Arena for allocations from class space
! // (NULL if -XX:-UseCompressedClassPointers).
! metaspace::MetaspaceArena* _class_space_arena;
Mutex* lock() const { return _lock; }
+ metaspace::MetaspaceArena* non_class_space_arena() const { return _non_class_space_arena; }
+ metaspace::MetaspaceArena* class_space_arena() const { return _class_space_arena; }
! metaspace::MetaspaceArena* get_arena(bool is_class) {
! return is_class ? class_space_arena() : non_class_space_arena();
! }
! public:
! ClassLoaderMetaspace(Mutex* lock, Metaspace::MetaspaceType space_type);
~ClassLoaderMetaspace();
! Metaspace::MetaspaceType space_type() const { return _space_type; }
! // Allocate word_size words from Metaspace.
! MetaWord* allocate(size_t word_size, Metaspace::MetadataType mdType);
! // Attempt to expand the GC threshold to be good for at least another word_size words
! // and allocate. Returns NULL if failure. Used during Metaspace GC.
! MetaWord* expand_and_allocate(size_t word_size, Metaspace::MetadataType mdType);
! // Prematurely returns a metaspace allocation to the _block_freelists
! // because it is not needed anymore.
! void deallocate(MetaWord* ptr, size_t word_size, bool is_class);
! // Update statistics. This walks all in-use chunks.
! void add_to_statistics(metaspace::clms_stats_t* out) const;
! DEBUG_ONLY(void verify() const;)
! // This only exists for JFR and jcmd VM.classloader_stats. We may want to
! // change this. Capacity as a stat is of questionable use since it may
! // contain committed and uncommitted areas. For now we do this to maintain
! // backward compatibility with JFR.
! void calculate_jfr_stats(size_t* p_used_bytes, size_t* p_capacity_bytes) const;
! }; // end: ClassLoaderMetaspace
! ////////////////// MetaspaceGC ///////////////////////
! // Metaspace are deallocated when their class loader are GC'ed.
! // This class implements a policy for inducing GC's to recover
! // Metaspaces.
! class MetaspaceGCThresholdUpdater : public AllStatic {
! public:
! enum Type {
! ComputeNewSize,
! ExpandAndAllocate,
! Last
};
! static const char* to_string(MetaspaceGCThresholdUpdater::Type updater) {
! switch (updater) {
! case ComputeNewSize:
! return "compute_new_size";
! case ExpandAndAllocate:
! return "expand_and_allocate";
! default:
! assert(false, "Got bad updater: %d", (int) updater);
! return NULL;
! };
! }
};
! class MetaspaceGC : public AllStatic {
// The current high-water-mark for inducing a GC.
// When committed memory of all metaspaces reaches this value,
// a GC is induced and the value is increased. Size is in bytes.
static volatile size_t _capacity_until_GC;
*** 475,480 ****
--- 289,343 ----
// Calculate the new high-water mark at which to induce
// a GC.
static void compute_new_size();
};
+
+
+
+ class MetaspaceUtils : AllStatic {
+ public:
+
+ // Committed space actually in use by Metadata
+ static size_t used_words();
+ static size_t used_words(Metaspace::MetadataType mdtype);
+
+ // Space committed for Metaspace
+ static size_t committed_words();
+ static size_t committed_words(Metaspace::MetadataType mdtype);
+
+ // Space reserved for Metaspace
+ static size_t reserved_words();
+ static size_t reserved_words(Metaspace::MetadataType mdtype);
+
+ // _bytes() variants for convenience...
+ static size_t used_bytes() { return used_words() * BytesPerWord; }
+ static size_t used_bytes(Metaspace::MetadataType mdtype) { return used_words(mdtype) * BytesPerWord; }
+ static size_t committed_bytes() { return committed_words() * BytesPerWord; }
+ static size_t committed_bytes(Metaspace::MetadataType mdtype) { return committed_words(mdtype) * BytesPerWord; }
+ static size_t reserved_bytes() { return reserved_words() * BytesPerWord; }
+ static size_t reserved_bytes(Metaspace::MetadataType mdtype) { return reserved_words(mdtype) * BytesPerWord; }
+
+ // (See JDK-8251342). Implement or Consolidate.
+ static MetaspaceChunkFreeListSummary chunk_free_list_summary(Metaspace::MetadataType mdtype) {
+ return MetaspaceChunkFreeListSummary(0,0,0,0,0,0,0,0);
+ }
+
+ // Log change in used metadata.
+ static void print_metaspace_change(const metaspace::MetaspaceSizesSnapshot& pre_meta_values);
+
+ // This will print out a basic metaspace usage report but
+ // unlike print_report() is guaranteed not to lock or to walk the CLDG.
+ static void print_basic_report(outputStream* st, size_t scale = 0);
+
+ // Prints a report about the current metaspace state.
+ // Function will walk the CLDG and will lock the expand lock; if that is not
+ // convenient, use print_basic_report() instead.
+ static void print_report(outputStream* out, size_t scale = 0);
+
+ static void print_on(outputStream * out);
+
+ DEBUG_ONLY(static void verify(bool slow);)
+
+ };
+
#endif // SHARE_MEMORY_METASPACE_HPP
< prev index next >