src/hotspot/share/memory/metaspace/spaceManager.cpp
branchstuefe-new-metaspace-branch
changeset 58883 08102295011d
parent 58882 58b20be7bc04
child 59107 245a39d9e24d
equal deleted inserted replaced
58882:58b20be7bc04 58883:08102295011d
   101             "Requested size too large (" SIZE_FORMAT ") - max allowed size per allocation is " SIZE_FORMAT ".",
   101             "Requested size too large (" SIZE_FORMAT ") - max allowed size per allocation is " SIZE_FORMAT ".",
   102             requested_word_size, chklvl::MAX_CHUNK_WORD_SIZE);
   102             requested_word_size, chklvl::MAX_CHUNK_WORD_SIZE);
   103 
   103 
   104   // If we have a current chunk, it should have been retired (almost empty) beforehand.
   104   // If we have a current chunk, it should have been retired (almost empty) beforehand.
   105   // See: retire_current_chunk().
   105   // See: retire_current_chunk().
   106   assert(current_chunk() == NULL || current_chunk()->free_below_committed_words() <= 10, "Must retire chunk beforehand");
   106   assert(current_chunk() == NULL ||
       
   107          (_is_micro_loader || current_chunk()->free_below_committed_words() <= 10), "Must retire chunk beforehand");
   107 
   108 
   108   const chklvl_t min_level = chklvl::level_fitting_word_size(requested_word_size);
   109   const chklvl_t min_level = chklvl::level_fitting_word_size(requested_word_size);
   109   chklvl_t pref_level = _chunk_alloc_sequence->get_next_chunk_level(_chunks.size());
   110   chklvl_t pref_level = _chunk_alloc_sequence->get_next_chunk_level(_chunks.size());
   110 
   111 
   111   if (pref_level > min_level) {
   112   if (pref_level > min_level) {
   157 
   158 
   158 SpaceManager::SpaceManager(ChunkManager* chunk_manager,
   159 SpaceManager::SpaceManager(ChunkManager* chunk_manager,
   159              const ChunkAllocSequence* alloc_sequence,
   160              const ChunkAllocSequence* alloc_sequence,
   160              Mutex* lock,
   161              Mutex* lock,
   161              SizeAtomicCounter* total_used_words_counter,
   162              SizeAtomicCounter* total_used_words_counter,
   162              const char* name)
   163              const char* name,
       
   164              bool is_micro_loader)
   163 : _lock(lock),
   165 : _lock(lock),
   164   _chunk_manager(chunk_manager),
   166   _chunk_manager(chunk_manager),
   165   _chunk_alloc_sequence(alloc_sequence),
   167   _chunk_alloc_sequence(alloc_sequence),
   166   _chunks(),
   168   _chunks(),
   167   _block_freelist(NULL),
   169   _block_freelist(NULL),
   168   _total_used_words_counter(total_used_words_counter),
   170   _total_used_words_counter(total_used_words_counter),
   169   _name(name)
   171   _name(name),
       
   172   _is_micro_loader(is_micro_loader)
   170 {
   173 {
   171 }
   174 }
   172 
   175 
   173 SpaceManager::~SpaceManager() {
   176 SpaceManager::~SpaceManager() {
   174 
   177 
   205   // But since these cases should be exceedingly rare, we do not handle them special in order to keep
   208   // But since these cases should be exceedingly rare, we do not handle them special in order to keep
   206   // the code simple.
   209   // the code simple.
   207 
   210 
   208   size_t raw_remaining_words = c->free_below_committed_words();
   211   size_t raw_remaining_words = c->free_below_committed_words();
   209   size_t net_remaining_words = get_net_allocation_word_size(raw_remaining_words);
   212   size_t net_remaining_words = get_net_allocation_word_size(raw_remaining_words);
   210   if (net_remaining_words > 0) {
   213 
       
   214   // Note: Micro class loaders (lambdas, reflection) are typically the vast majority of loaders. They
       
   215   //  will typically only once - if at all - ever retire a chunk, and the remaining size is typically
       
   216   //  very small.
       
   217   // That means that the structure needed to manage this left over space will not see much action. However,
       
   218   //  that structure is expensive as well (pointer lists) and therefore we only should generate it if the
       
   219   //  benefit of managing free space out-weights the costs for that structure.
       
   220   // Non-micro loaders may continue loading, deallocating and retiring more chunks, so the cost of that
       
   221   //  structure may amortize over time. But micro loaders probably never will.
       
   222   const size_t dont_bother_below_word_size = _is_micro_loader ? 64 : 0;
       
   223 
       
   224   if (net_remaining_words > dont_bother_below_word_size) {
   211 
   225 
   212     log_debug(metaspace)(LOGFMT_SPCMGR " @" PTR_FORMAT " : retiring chunk " METACHUNK_FULL_FORMAT ".",
   226     log_debug(metaspace)(LOGFMT_SPCMGR " @" PTR_FORMAT " : retiring chunk " METACHUNK_FULL_FORMAT ".",
   213                          LOGFMT_SPCMGR_ARGS, p2i(this), METACHUNK_FULL_FORMAT_ARGS(c));
   227                          LOGFMT_SPCMGR_ARGS, p2i(this), METACHUNK_FULL_FORMAT_ARGS(c));
   214 
   228 
   215     bool did_hit_limit = false;
   229     bool did_hit_limit = false;
   223            "Chunk retiring did not work (current chunk " METACHUNK_FULL_FORMAT ").",
   237            "Chunk retiring did not work (current chunk " METACHUNK_FULL_FORMAT ").",
   224            METACHUNK_FULL_FORMAT_ARGS(current_chunk()));
   238            METACHUNK_FULL_FORMAT_ARGS(current_chunk()));
   225 
   239 
   226     DEBUG_ONLY(verify_locked();)
   240     DEBUG_ONLY(verify_locked();)
   227 
   241 
       
   242     DEBUG_ONLY(InternalStats::inc_num_chunks_retired();)
   228   }
   243   }
   229 
   244 
   230 }
   245 }
   231 
   246 
   232 // Allocate memory from Metaspace.
   247 // Allocate memory from Metaspace.
   332 
   347 
   333     // Before we allocate a new chunk we need to retire the old chunk, which is too small to serve our request
   348     // Before we allocate a new chunk we need to retire the old chunk, which is too small to serve our request
   334     // but may still have free committed words.
   349     // but may still have free committed words.
   335     retire_current_chunk();
   350     retire_current_chunk();
   336 
   351 
   337     DEBUG_ONLY(InternalStats::inc_num_chunks_retired();)
       
   338 
       
   339     // Allocate a new chunk.
   352     // Allocate a new chunk.
   340     if (allocate_new_current_chunk(raw_word_size) == false) {
   353     if (allocate_new_current_chunk(raw_word_size) == false) {
   341       did_hit_limit = true;
   354       did_hit_limit = true;
   342     } else {
   355     } else {
   343       assert(current_chunk() != NULL && current_chunk()->free_words() >= raw_word_size, "Sanity");
   356       assert(current_chunk() != NULL && current_chunk()->free_words() >= raw_word_size, "Sanity");