src/hotspot/share/memory/metaspace.cpp
branchstuefe-improved-metaspace
changeset 57464 32e61f51ee09
parent 55586 014c8cd323af
equal deleted inserted replaced
55634:0f1e29c77e50 57464:32e61f51ee09
    30 #include "logging/logStream.hpp"
    30 #include "logging/logStream.hpp"
    31 #include "memory/filemap.hpp"
    31 #include "memory/filemap.hpp"
    32 #include "memory/metaspace.hpp"
    32 #include "memory/metaspace.hpp"
    33 #include "memory/metaspace/chunkManager.hpp"
    33 #include "memory/metaspace/chunkManager.hpp"
    34 #include "memory/metaspace/metachunk.hpp"
    34 #include "memory/metaspace/metachunk.hpp"
    35 #include "memory/metaspace/metaspaceCommon.hpp"
    35 #include "memory/metaspace/chunkLevel.hpp"
    36 #include "memory/metaspace/printCLDMetaspaceInfoClosure.hpp"
    36 #include "memory/metaspace/printCLDMetaspaceInfoClosure.hpp"
    37 #include "memory/metaspace/spaceManager.hpp"
    37 #include "memory/metaspace/spaceManager.hpp"
    38 #include "memory/metaspace/virtualSpaceList.hpp"
    38 #include "memory/metaspace/virtualSpaceList.hpp"
    39 #include "memory/metaspaceShared.hpp"
    39 #include "memory/metaspaceShared.hpp"
    40 #include "memory/metaspaceTracer.hpp"
    40 #include "memory/metaspaceTracer.hpp"
   955 #endif
   955 #endif
   956 }
   956 }
   957 
   957 
   958 // Metaspace methods
   958 // Metaspace methods
   959 
   959 
   960 size_t Metaspace::_first_chunk_word_size = 0;
       
   961 size_t Metaspace::_first_class_chunk_word_size = 0;
       
   962 
       
   963 size_t Metaspace::_commit_alignment = 0;
       
   964 size_t Metaspace::_reserve_alignment = 0;
       
   965 
       
   966 VirtualSpaceList* Metaspace::_space_list = NULL;
   960 VirtualSpaceList* Metaspace::_space_list = NULL;
   967 VirtualSpaceList* Metaspace::_class_space_list = NULL;
   961 VirtualSpaceList* Metaspace::_class_space_list = NULL;
   968 
   962 
   969 ChunkManager* Metaspace::_chunk_manager_metadata = NULL;
   963 ChunkManager* Metaspace::_chunk_manager_metadata = NULL;
   970 ChunkManager* Metaspace::_chunk_manager_class = NULL;
   964 ChunkManager* Metaspace::_chunk_manager_class = NULL;
  1176 void Metaspace::initialize_class_space(ReservedSpace rs) {
  1170 void Metaspace::initialize_class_space(ReservedSpace rs) {
  1177   // The reserved space size may be bigger because of alignment, esp with UseLargePages
  1171   // The reserved space size may be bigger because of alignment, esp with UseLargePages
  1178   assert(rs.size() >= CompressedClassSpaceSize,
  1172   assert(rs.size() >= CompressedClassSpaceSize,
  1179          SIZE_FORMAT " != " SIZE_FORMAT, rs.size(), CompressedClassSpaceSize);
  1173          SIZE_FORMAT " != " SIZE_FORMAT, rs.size(), CompressedClassSpaceSize);
  1180   assert(using_class_space(), "Must be using class space");
  1174   assert(using_class_space(), "Must be using class space");
  1181   _class_space_list = new VirtualSpaceList(rs);
  1175   _class_space_list = new VirtualSpaceList("class space list", rs);
  1182   _chunk_manager_class = new ChunkManager(true/*is_class*/);
  1176   _chunk_manager_class = new ChunkManager("class space chunk manager", _class_space_list);
  1183 
  1177 
  1184   if (!_class_space_list->initialization_succeeded()) {
       
  1185     vm_exit_during_initialization("Failed to setup compressed class space virtual space list.");
       
  1186   }
       
  1187 }
  1178 }
  1188 
  1179 
  1189 #endif
  1180 #endif
  1190 
  1181 
  1191 void Metaspace::ergo_initialize() {
  1182 void Metaspace::ergo_initialize() {
  1198   if (UseLargePages && UseLargePagesInMetaspace) {
  1189   if (UseLargePages && UseLargePagesInMetaspace) {
  1199     page_size = os::large_page_size();
  1190     page_size = os::large_page_size();
  1200   }
  1191   }
  1201 
  1192 
  1202   _commit_alignment  = page_size;
  1193   _commit_alignment  = page_size;
  1203   _reserve_alignment = MAX2(page_size, (size_t)os::vm_allocation_granularity());
  1194 
       
  1195   // Reserve alignment: all Metaspace memory mappings are to be aligned to the size of a root chunk.
       
  1196   assert(is_aligned_to((int)MAX_CHUNK_BYTE_SIZE, os::vm_allocation_granularity()),
       
  1197       "root chunk size must be a multiple of alloc granularity");
       
  1198 
       
  1199   _reserve_alignment = MAX2(page_size, (size_t)MAX_CHUNK_BYTE_SIZE);
  1204 
  1200 
  1205   // Do not use FLAG_SET_ERGO to update MaxMetaspaceSize, since this will
  1201   // Do not use FLAG_SET_ERGO to update MaxMetaspaceSize, since this will
  1206   // override if MaxMetaspaceSize was set on the command line or not.
  1202   // override if MaxMetaspaceSize was set on the command line or not.
  1207   // This information is needed later to conform to the specification of the
  1203   // This information is needed later to conform to the specification of the
  1208   // java.lang.management.MemoryUsage API.
  1204   // java.lang.management.MemoryUsage API.
  1244 
  1240 
  1245   set_compressed_class_space_size(CompressedClassSpaceSize);
  1241   set_compressed_class_space_size(CompressedClassSpaceSize);
  1246 }
  1242 }
  1247 
  1243 
  1248 void Metaspace::global_initialize() {
  1244 void Metaspace::global_initialize() {
  1249   MetaspaceGC::initialize();
  1245   MetaspaceGC::initialize(); // <- since we do not prealloc init chunks anymore is this still needed?
  1250 
  1246 
  1251 #if INCLUDE_CDS
  1247 #if INCLUDE_CDS
  1252   if (DumpSharedSpaces) {
  1248   if (DumpSharedSpaces) {
  1253     MetaspaceShared::initialize_dumptime_shared_and_meta_spaces();
  1249     MetaspaceShared::initialize_dumptime_shared_and_meta_spaces();
  1254   } else if (UseSharedSpaces) {
  1250   } else if (UseSharedSpaces) {
  1260   }
  1256   }
  1261 
  1257 
  1262   if (DynamicDumpSharedSpaces && !UseSharedSpaces) {
  1258   if (DynamicDumpSharedSpaces && !UseSharedSpaces) {
  1263     vm_exit_during_initialization("DynamicDumpSharedSpaces is unsupported when base CDS archive is not loaded", NULL);
  1259     vm_exit_during_initialization("DynamicDumpSharedSpaces is unsupported when base CDS archive is not loaded", NULL);
  1264   }
  1260   }
  1265 
       
  1266   if (!DumpSharedSpaces && !UseSharedSpaces)
       
  1267 #endif // INCLUDE_CDS
  1261 #endif // INCLUDE_CDS
  1268   {
  1262 
       
  1263   // Initialize class space:
       
  1264   if (CDS_ONLY(!DumpSharedSpaces && !UseSharedSpaces) NOT_CDS(true)) {
  1269 #ifdef _LP64
  1265 #ifdef _LP64
  1270     if (using_class_space()) {
  1266     if (using_class_space()) {
  1271       char* base = (char*)align_up(Universe::heap()->reserved_region().end(), _reserve_alignment);
  1267       char* base = (char*)align_up(Universe::heap()->reserved_region().end(), _reserve_alignment);
  1272       allocate_metaspace_compressed_klass_ptrs(base, 0);
  1268       allocate_metaspace_compressed_klass_ptrs(base, 0);
  1273     }
  1269     }
  1274 #endif // _LP64
  1270 #endif // _LP64
  1275   }
  1271   }
  1276 
  1272 
  1277   // Initialize these before initializing the VirtualSpaceList
  1273   // Initialize non-class virtual space list, and its chunk manager:
  1278   _first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord;
  1274   _space_list = new VirtualSpaceList("Non-Class VirtualSpaceList");
  1279   _first_chunk_word_size = align_word_size_up(_first_chunk_word_size);
  1275   _chunk_manager_metadata = new ChunkManager("Non-Class ChunkManager", _space_list);
  1280   // Make the first class chunk bigger than a medium chunk so it's not put
       
  1281   // on the medium chunk list.   The next chunk will be small and progress
       
  1282   // from there.  This size calculated by -version.
       
  1283   _first_class_chunk_word_size = MIN2((size_t)MediumChunk*6,
       
  1284                                      (CompressedClassSpaceSize/BytesPerWord)*2);
       
  1285   _first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size);
       
  1286   // Arbitrarily set the initial virtual space to a multiple
       
  1287   // of the boot class loader size.
       
  1288   size_t word_size = VIRTUALSPACEMULTIPLIER * _first_chunk_word_size;
       
  1289   word_size = align_up(word_size, Metaspace::reserve_alignment_words());
       
  1290 
       
  1291   // Initialize the list of virtual spaces.
       
  1292   _space_list = new VirtualSpaceList(word_size);
       
  1293   _chunk_manager_metadata = new ChunkManager(false/*metaspace*/);
       
  1294 
       
  1295   if (!_space_list->initialization_succeeded()) {
       
  1296     vm_exit_during_initialization("Unable to setup metadata virtual space list.", NULL);
       
  1297   }
       
  1298 
  1276 
  1299   _tracer = new MetaspaceTracer();
  1277   _tracer = new MetaspaceTracer();
  1300 
  1278 
  1301   _initialized = true;
  1279   _initialized = true;
  1302 
  1280 
  1458   }
  1436   }
  1459 
  1437 
  1460   return get_space_list(NonClassType)->contains(ptr);
  1438   return get_space_list(NonClassType)->contains(ptr);
  1461 }
  1439 }
  1462 
  1440 
  1463 // ClassLoaderMetaspace
       
  1464 
       
  1465 ClassLoaderMetaspace::ClassLoaderMetaspace(Mutex* lock, Metaspace::MetaspaceType type)
       
  1466   : _space_type(type)
       
  1467   , _lock(lock)
       
  1468   , _vsm(NULL)
       
  1469   , _class_vsm(NULL)
       
  1470 {
       
  1471   initialize(lock, type);
       
  1472 }
       
  1473 
       
  1474 ClassLoaderMetaspace::~ClassLoaderMetaspace() {
       
  1475   Metaspace::assert_not_frozen();
       
  1476   DEBUG_ONLY(Atomic::inc(&g_internal_statistics.num_metaspace_deaths));
       
  1477   delete _vsm;
       
  1478   if (Metaspace::using_class_space()) {
       
  1479     delete _class_vsm;
       
  1480   }
       
  1481 }
       
  1482 
       
  1483 void ClassLoaderMetaspace::initialize_first_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype) {
       
  1484   Metachunk* chunk = get_initialization_chunk(type, mdtype);
       
  1485   if (chunk != NULL) {
       
  1486     // Add to this manager's list of chunks in use and make it the current_chunk().
       
  1487     get_space_manager(mdtype)->add_chunk(chunk, true);
       
  1488   }
       
  1489 }
       
  1490 
       
  1491 Metachunk* ClassLoaderMetaspace::get_initialization_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype) {
       
  1492   size_t chunk_word_size = get_space_manager(mdtype)->get_initial_chunk_size(type);
       
  1493 
       
  1494   // Get a chunk from the chunk freelist
       
  1495   Metachunk* chunk = Metaspace::get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size);
       
  1496 
       
  1497   if (chunk == NULL) {
       
  1498     chunk = Metaspace::get_space_list(mdtype)->get_new_chunk(chunk_word_size,
       
  1499                                                   get_space_manager(mdtype)->medium_chunk_bunch());
       
  1500   }
       
  1501 
       
  1502   return chunk;
       
  1503 }
       
  1504 
       
  1505 void ClassLoaderMetaspace::initialize(Mutex* lock, Metaspace::MetaspaceType type) {
       
  1506   Metaspace::verify_global_initialization();
       
  1507 
       
  1508   DEBUG_ONLY(Atomic::inc(&g_internal_statistics.num_metaspace_births));
       
  1509 
       
  1510   // Allocate SpaceManager for metadata objects.
       
  1511   _vsm = new SpaceManager(Metaspace::NonClassType, type, lock);
       
  1512 
       
  1513   if (Metaspace::using_class_space()) {
       
  1514     // Allocate SpaceManager for classes.
       
  1515     _class_vsm = new SpaceManager(Metaspace::ClassType, type, lock);
       
  1516   }
       
  1517 
       
  1518   MutexLocker cl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
       
  1519 
       
  1520   // Allocate chunk for metadata objects
       
  1521   initialize_first_chunk(type, Metaspace::NonClassType);
       
  1522 
       
  1523   // Allocate chunk for class metadata objects
       
  1524   if (Metaspace::using_class_space()) {
       
  1525     initialize_first_chunk(type, Metaspace::ClassType);
       
  1526   }
       
  1527 }
       
  1528 
       
  1529 MetaWord* ClassLoaderMetaspace::allocate(size_t word_size, Metaspace::MetadataType mdtype) {
       
  1530   Metaspace::assert_not_frozen();
       
  1531 
       
  1532   DEBUG_ONLY(Atomic::inc(&g_internal_statistics.num_allocs));
       
  1533 
       
  1534   // Don't use class_vsm() unless UseCompressedClassPointers is true.
       
  1535   if (Metaspace::is_class_space_allocation(mdtype)) {
       
  1536     return  class_vsm()->allocate(word_size);
       
  1537   } else {
       
  1538     return  vsm()->allocate(word_size);
       
  1539   }
       
  1540 }
       
  1541 
       
  1542 MetaWord* ClassLoaderMetaspace::expand_and_allocate(size_t word_size, Metaspace::MetadataType mdtype) {
       
  1543   Metaspace::assert_not_frozen();
       
  1544   size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord);
       
  1545   assert(delta_bytes > 0, "Must be");
       
  1546 
       
  1547   size_t before = 0;
       
  1548   size_t after = 0;
       
  1549   bool can_retry = true;
       
  1550   MetaWord* res;
       
  1551   bool incremented;
       
  1552 
       
  1553   // Each thread increments the HWM at most once. Even if the thread fails to increment
       
  1554   // the HWM, an allocation is still attempted. This is because another thread must then
       
  1555   // have incremented the HWM and therefore the allocation might still succeed.
       
  1556   do {
       
  1557     incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before, &can_retry);
       
  1558     res = allocate(word_size, mdtype);
       
  1559   } while (!incremented && res == NULL && can_retry);
       
  1560 
       
  1561   if (incremented) {
       
  1562     Metaspace::tracer()->report_gc_threshold(before, after,
       
  1563                                   MetaspaceGCThresholdUpdater::ExpandAndAllocate);
       
  1564     log_trace(gc, metaspace)("Increase capacity to GC from " SIZE_FORMAT " to " SIZE_FORMAT, before, after);
       
  1565   }
       
  1566 
       
  1567   return res;
       
  1568 }
       
  1569 
       
  1570 size_t ClassLoaderMetaspace::allocated_blocks_bytes() const {
       
  1571   return (vsm()->used_words() +
       
  1572       (Metaspace::using_class_space() ? class_vsm()->used_words() : 0)) * BytesPerWord;
       
  1573 }
       
  1574 
       
  1575 size_t ClassLoaderMetaspace::allocated_chunks_bytes() const {
       
  1576   return (vsm()->capacity_words() +
       
  1577       (Metaspace::using_class_space() ? class_vsm()->capacity_words() : 0)) * BytesPerWord;
       
  1578 }
       
  1579 
       
  1580 void ClassLoaderMetaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
       
  1581   Metaspace::assert_not_frozen();
       
  1582   assert(!SafepointSynchronize::is_at_safepoint()
       
  1583          || Thread::current()->is_VM_thread(), "should be the VM thread");
       
  1584 
       
  1585   DEBUG_ONLY(Atomic::inc(&g_internal_statistics.num_external_deallocs));
       
  1586 
       
  1587   MutexLocker ml(vsm()->lock(), Mutex::_no_safepoint_check_flag);
       
  1588 
       
  1589   if (is_class && Metaspace::using_class_space()) {
       
  1590     class_vsm()->deallocate(ptr, word_size);
       
  1591   } else {
       
  1592     vsm()->deallocate(ptr, word_size);
       
  1593   }
       
  1594 }
       
  1595 
       
  1596 size_t ClassLoaderMetaspace::class_chunk_size(size_t word_size) {
       
  1597   assert(Metaspace::using_class_space(), "Has to use class space");
       
  1598   return class_vsm()->calc_chunk_size(word_size);
       
  1599 }
       
  1600 
       
  1601 void ClassLoaderMetaspace::print_on(outputStream* out) const {
       
  1602   // Print both class virtual space counts and metaspace.
       
  1603   if (Verbose) {
       
  1604     vsm()->print_on(out);
       
  1605     if (Metaspace::using_class_space()) {
       
  1606       class_vsm()->print_on(out);
       
  1607     }
       
  1608   }
       
  1609 }
       
  1610 
       
  1611 void ClassLoaderMetaspace::verify() {
       
  1612   vsm()->verify();
       
  1613   if (Metaspace::using_class_space()) {
       
  1614     class_vsm()->verify();
       
  1615   }
       
  1616 }
       
  1617 
       
  1618 void ClassLoaderMetaspace::add_to_statistics_locked(ClassLoaderMetaspaceStatistics* out) const {
       
  1619   assert_lock_strong(lock());
       
  1620   vsm()->add_to_statistics_locked(&out->nonclass_sm_stats());
       
  1621   if (Metaspace::using_class_space()) {
       
  1622     class_vsm()->add_to_statistics_locked(&out->class_sm_stats());
       
  1623   }
       
  1624 }
       
  1625 
       
  1626 void ClassLoaderMetaspace::add_to_statistics(ClassLoaderMetaspaceStatistics* out) const {
       
  1627   MutexLocker cl(lock(), Mutex::_no_safepoint_check_flag);
       
  1628   add_to_statistics_locked(out);
       
  1629 }
       
  1630 
       
  1631 /////////////// Unit tests ///////////////
  1441 /////////////// Unit tests ///////////////
  1632 
  1442 
  1633 struct chunkmanager_statistics_t {
  1443 struct chunkmanager_statistics_t {
  1634   int num_specialized_chunks;
  1444   int num_specialized_chunks;
  1635   int num_small_chunks;
  1445   int num_small_chunks;