src/share/vm/memory/metaspace.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/memory

src/share/vm/memory/metaspace.cpp

Print this page




 598 
 599 //  SpaceManager - used by Metaspace to handle allocations
 600 class SpaceManager : public CHeapObj<mtClass> {
 601   friend class Metaspace;
 602   friend class Metadebug;
 603 
 604  private:
 605 
 606   // protects allocations
 607   Mutex* const _lock;
 608 
 609   // Type of metadata allocated.
 610   Metaspace::MetadataType _mdtype;
 611 
 612   // List of chunks in use by this SpaceManager.  Allocations
 613   // are done from the current chunk.  The list is used for deallocating
 614   // chunks when the SpaceManager is freed.
 615   Metachunk* _chunks_in_use[NumberOfInUseLists];
 616   Metachunk* _current_chunk;
 617 
 618   // Number of small chunks to allocate to a manager
 619   // If class space manager, small chunks are unlimited
 620   static uint const _small_chunk_limit;
 621 
 622   // Sum of all space in allocated chunks
 623   size_t _allocated_blocks_words;
 624 
 625   // Sum of all allocated chunks
 626   size_t _allocated_chunks_words;
 627   size_t _allocated_chunks_count;
 628 
 629   // Free lists of blocks are per SpaceManager since they
 630   // are assumed to be in chunks in use by the SpaceManager
 631   // and all chunks in use by a SpaceManager are freed when
 632   // the class loader using the SpaceManager is collected.
 633   BlockFreelist _block_freelists;
 634 
 635   // protects virtualspace and chunk expansions
 636   static const char*  _expand_lock_name;
 637   static const int    _expand_lock_rank;
 638   static Mutex* const _expand_lock;
 639 


1995 
1996   for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1997     Metachunk* chunk = chunks_in_use(i);
1998     st->print("SpaceManager: %s " PTR_FORMAT,
1999                  chunk_size_name(i), p2i(chunk));
2000     if (chunk != NULL) {
2001       st->print_cr(" free " SIZE_FORMAT,
2002                    chunk->free_word_size());
2003     } else {
2004       st->cr();
2005     }
2006   }
2007 
2008   chunk_manager()->locked_print_free_chunks(st);
2009   chunk_manager()->locked_print_sum_free_chunks(st);
2010 }
2011 
2012 size_t SpaceManager::calc_chunk_size(size_t word_size) {
2013 
2014   // Decide between a small chunk and a medium chunk.  Up to
2015   // _small_chunk_limit small chunks can be allocated but
2016   // once a medium chunk has been allocated, no more small
2017   // chunks will be allocated.
2018   size_t chunk_word_size;
2019   if (chunks_in_use(MediumIndex) == NULL &&
2020       sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
2021     chunk_word_size = (size_t) small_chunk_size();
2022     if (word_size + Metachunk::overhead() > small_chunk_size()) {
2023       chunk_word_size = medium_chunk_size();
2024     }
2025   } else {
2026     chunk_word_size = medium_chunk_size();
2027   }
2028 
2029   // Might still need a humongous chunk.  Enforce
2030   // humongous allocations sizes to be aligned up to
2031   // the smallest chunk size.
2032   size_t if_humongous_sized_chunk =
2033     align_size_up(word_size + Metachunk::overhead(),
2034                   smallest_chunk_size());
2035   chunk_word_size =
2036     MAX2((size_t) chunk_word_size, if_humongous_sized_chunk);
2037 


2044       SpaceManager::is_humongous(word_size)) {
2045     gclog_or_tty->print_cr("Metadata humongous allocation:");
2046     gclog_or_tty->print_cr("  word_size " PTR_FORMAT, word_size);
2047     gclog_or_tty->print_cr("  chunk_word_size " PTR_FORMAT,
2048                            chunk_word_size);
2049     gclog_or_tty->print_cr("    chunk overhead " PTR_FORMAT,
2050                            Metachunk::overhead());
2051   }
2052   return chunk_word_size;
2053 }
2054 
2055 void SpaceManager::track_metaspace_memory_usage() {
2056   if (is_init_completed()) {
2057     if (is_class()) {
2058       MemoryService::track_compressed_class_memory_usage();
2059     }
2060     MemoryService::track_metaspace_memory_usage();
2061   }
2062 }
2063 










2064 MetaWord* SpaceManager::grow_and_allocate(size_t word_size) {
2065   assert(vs_list()->current_virtual_space() != NULL,
2066          "Should have been set");
2067   assert(current_chunk() == NULL ||
2068          current_chunk()->allocate(word_size) == NULL,
2069          "Don't need to expand");
2070   MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
2071 
2072   if (TraceMetadataChunkAllocation && Verbose) {
2073     size_t words_left = 0;
2074     size_t words_used = 0;
2075     if (current_chunk() != NULL) {
2076       words_left = current_chunk()->free_word_size();
2077       words_used = current_chunk()->used_word_size();
2078     }
2079     gclog_or_tty->print_cr("SpaceManager::grow_and_allocate for " SIZE_FORMAT
2080                            " words " SIZE_FORMAT " words used " SIZE_FORMAT
2081                            " words left",
2082                             word_size, words_used, words_left);
2083   }
2084 
2085   // Get another chunk out of the virtual space
2086   size_t grow_chunks_by_words = calc_chunk_size(word_size);
2087   Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words);
2088 
2089   MetaWord* mem = NULL;










2090 
2091   // If a chunk was available, add it to the in-use chunk list
2092   // and do an allocation from it.
2093   if (next != NULL) {
2094     // Add to this manager's list of chunks in use.
2095     add_chunk(next, false);
2096     mem = next->allocate(word_size);
2097   }
2098 
2099   // Track metaspace memory usage statistic.
2100   track_metaspace_memory_usage();
2101 
2102   return mem;
2103 }
2104 
2105 void SpaceManager::print_on(outputStream* st) const {
2106 
2107   for (ChunkIndex i = ZeroIndex;
2108        i < NumberOfInUseLists ;
2109        i = next_chunk_index(i) ) {




 598 
 599 //  SpaceManager - used by Metaspace to handle allocations
 600 class SpaceManager : public CHeapObj<mtClass> {
 601   friend class Metaspace;
 602   friend class Metadebug;
 603 
 604  private:
 605 
 606   // protects allocations
 607   Mutex* const _lock;
 608 
 609   // Type of metadata allocated.
 610   Metaspace::MetadataType _mdtype;
 611 
 612   // List of chunks in use by this SpaceManager.  Allocations
 613   // are done from the current chunk.  The list is used for deallocating
 614   // chunks when the SpaceManager is freed.
 615   Metachunk* _chunks_in_use[NumberOfInUseLists];
 616   Metachunk* _current_chunk;
 617 
 618   // Maximum number of small chunks to allocate to a SpaceManager

 619   static uint const _small_chunk_limit;
 620 
 621   // Sum of all space in allocated chunks
 622   size_t _allocated_blocks_words;
 623 
 624   // Sum of all allocated chunks
 625   size_t _allocated_chunks_words;
 626   size_t _allocated_chunks_count;
 627 
 628   // Free lists of blocks are per SpaceManager since they
 629   // are assumed to be in chunks in use by the SpaceManager
 630   // and all chunks in use by a SpaceManager are freed when
 631   // the class loader using the SpaceManager is collected.
 632   BlockFreelist _block_freelists;
 633 
 634   // protects virtualspace and chunk expansions
 635   static const char*  _expand_lock_name;
 636   static const int    _expand_lock_rank;
 637   static Mutex* const _expand_lock;
 638 


1994 
1995   for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
1996     Metachunk* chunk = chunks_in_use(i);
1997     st->print("SpaceManager: %s " PTR_FORMAT,
1998                  chunk_size_name(i), p2i(chunk));
1999     if (chunk != NULL) {
2000       st->print_cr(" free " SIZE_FORMAT,
2001                    chunk->free_word_size());
2002     } else {
2003       st->cr();
2004     }
2005   }
2006 
2007   chunk_manager()->locked_print_free_chunks(st);
2008   chunk_manager()->locked_print_sum_free_chunks(st);
2009 }
2010 
2011 size_t SpaceManager::calc_chunk_size(size_t word_size) {
2012 
2013   // Decide between a small chunk and a medium chunk.  Up to
2014   // _small_chunk_limit small chunks can be allocated.
2015   // After that a medium chunk is preferred.

2016   size_t chunk_word_size;
2017   if (chunks_in_use(MediumIndex) == NULL &&
2018       sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
2019     chunk_word_size = (size_t) small_chunk_size();
2020     if (word_size + Metachunk::overhead() > small_chunk_size()) {
2021       chunk_word_size = medium_chunk_size();
2022     }
2023   } else {
2024     chunk_word_size = medium_chunk_size();
2025   }
2026 
2027   // Might still need a humongous chunk.  Enforce
2028   // humongous allocations sizes to be aligned up to
2029   // the smallest chunk size.
2030   size_t if_humongous_sized_chunk =
2031     align_size_up(word_size + Metachunk::overhead(),
2032                   smallest_chunk_size());
2033   chunk_word_size =
2034     MAX2((size_t) chunk_word_size, if_humongous_sized_chunk);
2035 


2042       SpaceManager::is_humongous(word_size)) {
2043     gclog_or_tty->print_cr("Metadata humongous allocation:");
2044     gclog_or_tty->print_cr("  word_size " PTR_FORMAT, word_size);
2045     gclog_or_tty->print_cr("  chunk_word_size " PTR_FORMAT,
2046                            chunk_word_size);
2047     gclog_or_tty->print_cr("    chunk overhead " PTR_FORMAT,
2048                            Metachunk::overhead());
2049   }
2050   return chunk_word_size;
2051 }
2052 
2053 void SpaceManager::track_metaspace_memory_usage() {
2054   if (is_init_completed()) {
2055     if (is_class()) {
2056       MemoryService::track_compressed_class_memory_usage();
2057     }
2058     MemoryService::track_metaspace_memory_usage();
2059   }
2060 }
2061 
2062 /*
2063  * The policy is to allocate up to _small_chunk_limit small chunks
2064  * after which only medium chunks are allocated.  This is done to
2065  * reduce fragmentation.  In some cases, this can result in a lot
2066  * of small chunks being allocated to the point where it's not
2067  * possible to expand.  If this happens, there may be no medium chunks
2068  * available and OOME would be thrown.  Instead of doing that,
2069  * if the allocation request size fits in a small chunk, an attempt
2070  * will be made to allocate a small chunk.
2071  */
2072 MetaWord* SpaceManager::grow_and_allocate(size_t word_size) {
2073   assert(vs_list()->current_virtual_space() != NULL,
2074          "Should have been set");
2075   assert(current_chunk() == NULL ||
2076          current_chunk()->allocate(word_size) == NULL,
2077          "Don't need to expand");
2078   MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
2079 
2080   if (TraceMetadataChunkAllocation && Verbose) {
2081     size_t words_left = 0;
2082     size_t words_used = 0;
2083     if (current_chunk() != NULL) {
2084       words_left = current_chunk()->free_word_size();
2085       words_used = current_chunk()->used_word_size();
2086     }
2087     gclog_or_tty->print_cr("SpaceManager::grow_and_allocate for " SIZE_FORMAT
2088                            " words " SIZE_FORMAT " words used " SIZE_FORMAT
2089                            " words left",
2090                             word_size, words_used, words_left);
2091   }
2092 
2093   // Get another chunk
2094   size_t grow_chunks_by_words = calc_chunk_size(word_size);
2095   Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words);
2096 
2097   MetaWord* mem = NULL;
2098 
2099   if (next == NULL &&
2100       word_size + Metachunk::overhead() <= small_chunk_size() &&
2101       grow_chunks_by_words == medium_chunk_size()) {
2102     /*
2103      * There are no medium chunks available but a small chunk is big enough.
2104      * See if a small chunk is available.
2105      */
2106     next = get_new_chunk(word_size, small_chunk_size());
2107   }
2108 
2109   // If a chunk was available, add it to the in-use chunk list
2110   // and do an allocation from it.
2111   if (next != NULL) {
2112     // Add to this manager's list of chunks in use.
2113     add_chunk(next, false);
2114     mem = next->allocate(word_size);
2115   }
2116 
2117   // Track metaspace memory usage statistic.
2118   track_metaspace_memory_usage();
2119 
2120   return mem;
2121 }
2122 
2123 void SpaceManager::print_on(outputStream* st) const {
2124 
2125   for (ChunkIndex i = ZeroIndex;
2126        i < NumberOfInUseLists ;
2127        i = next_chunk_index(i) ) {


src/share/vm/memory/metaspace.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File