8190729: Adjustment to anonymous metadata space chunk allocation algorithm
authorzgu
Mon, 27 Nov 2017 17:19:53 -0500
changeset 48148 385bed268108
parent 48144 364207a23251
child 48149 5a449dbca6d0
8190729: Adjustment to anonymous metadata space chunk allocation algorithm Summary: Adjusted anonymous metadata space chunk allocation algorithm to reduce waste Reviewed-by: stuefe, coleenp
src/hotspot/share/memory/metaspace.cpp
--- a/src/hotspot/share/memory/metaspace.cpp	Tue Nov 28 21:04:42 2017 +0530
+++ b/src/hotspot/share/memory/metaspace.cpp	Mon Nov 27 17:19:53 2017 -0500
@@ -785,7 +785,10 @@
   Mutex* const _lock;
 
   // Type of metadata allocated.
-  Metaspace::MetadataType _mdtype;
+  const Metaspace::MetadataType   _mdtype;
+
+  // Type of metaspace
+  const Metaspace::MetaspaceType  _space_type;
 
   // List of chunks in use by this SpaceManager.  Allocations
   // are done from the current chunk.  The list is used for deallocating
@@ -796,6 +799,10 @@
   // Maximum number of small chunks to allocate to a SpaceManager
   static uint const _small_chunk_limit;
 
+  // Maximum number of specialize chunks to allocate for anonymous
+  // metadata space to a SpaceManager
+  static uint const _anon_metadata_specialize_chunk_limit;
+
   // Sum of all space in allocated chunks
   size_t _allocated_blocks_words;
 
@@ -846,6 +853,7 @@
 
  public:
   SpaceManager(Metaspace::MetadataType mdtype,
+               Metaspace::MetaspaceType space_type,
                Mutex* lock);
   ~SpaceManager();
 
@@ -963,6 +971,7 @@
 };
 
 uint const SpaceManager::_small_chunk_limit = 4;
+uint const SpaceManager::_anon_metadata_specialize_chunk_limit = 4;
 
 const char* SpaceManager::_expand_lock_name =
   "SpaceManager chunk allocation lock";
@@ -2400,6 +2409,20 @@
   // _small_chunk_limit small chunks can be allocated.
   // After that a medium chunk is preferred.
   size_t chunk_word_size;
+
+  // Special case for anonymous metadata space.
+  // Anonymous metadata space is usually small, with majority within 1K - 2K range and
+  // rarely about 4K (64-bits JVM).
+  // Instead of jumping to SmallChunk after initial chunk exhausted, keeping allocation
+  // from SpecializeChunk up to _anon_metadata_specialize_chunk_limit (4) reduces space waste
+  // from 60+% to around 30%.
+  if (_space_type == Metaspace::AnonymousMetaspaceType &&
+      _mdtype == Metaspace::NonClassType &&
+      sum_count_in_chunks_in_use(SpecializedIndex) < _anon_metadata_specialize_chunk_limit &&
+      word_size + Metachunk::overhead() <= SpecializedChunk) {
+    return SpecializedChunk;
+  }
+
   if (chunks_in_use(MediumIndex) == NULL &&
       sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
     chunk_word_size = (size_t) small_chunk_size();
@@ -2504,8 +2527,10 @@
 }
 
 SpaceManager::SpaceManager(Metaspace::MetadataType mdtype,
+                           Metaspace::MetaspaceType space_type,
                            Mutex* lock) :
   _mdtype(mdtype),
+  _space_type(space_type),
   _allocated_blocks_words(0),
   _allocated_chunks_words(0),
   _allocated_chunks_count(0),
@@ -3781,11 +3806,11 @@
   verify_global_initialization();
 
   // Allocate SpaceManager for metadata objects.
-  _vsm = new SpaceManager(NonClassType, lock);
+  _vsm = new SpaceManager(NonClassType, type, lock);
 
   if (using_class_space()) {
     // Allocate SpaceManager for classes.
-    _class_vsm = new SpaceManager(ClassType, lock);
+    _class_vsm = new SpaceManager(ClassType, type, lock);
   }
 
   MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);