469 |
469 |
470 const ChunkManager* cm = Metaspace::get_chunk_manager(mdtype); |
470 const ChunkManager* cm = Metaspace::get_chunk_manager(mdtype); |
471 return cm->chunk_free_list_summary(); |
471 return cm->chunk_free_list_summary(); |
472 } |
472 } |
473 |
473 |
474 void MetaspaceUtils::print_metaspace_change(size_t prev_metadata_used) { |
474 void MetaspaceUtils::print_metaspace_change(const metaspace::MetaspaceSizesSnapshot& pre_meta_values) { |
475 log_info(gc, metaspace)("Metaspace: " SIZE_FORMAT "K->" SIZE_FORMAT "K(" SIZE_FORMAT "K)", |
475 const metaspace::MetaspaceSizesSnapshot meta_values; |
476 prev_metadata_used/K, used_bytes()/K, reserved_bytes()/K); |
476 |
|
477 if (Metaspace::using_class_space()) { |
|
478 log_info(gc, metaspace)(HEAP_CHANGE_FORMAT" " |
|
479 HEAP_CHANGE_FORMAT" " |
|
480 HEAP_CHANGE_FORMAT, |
|
481 HEAP_CHANGE_FORMAT_ARGS("Metaspace", |
|
482 pre_meta_values.used(), |
|
483 pre_meta_values.committed(), |
|
484 meta_values.used(), |
|
485 meta_values.committed()), |
|
486 HEAP_CHANGE_FORMAT_ARGS("NonClass", |
|
487 pre_meta_values.non_class_used(), |
|
488 pre_meta_values.non_class_committed(), |
|
489 meta_values.non_class_used(), |
|
490 meta_values.non_class_committed()), |
|
491 HEAP_CHANGE_FORMAT_ARGS("Class", |
|
492 pre_meta_values.class_used(), |
|
493 pre_meta_values.class_committed(), |
|
494 meta_values.class_used(), |
|
495 meta_values.class_committed())); |
|
496 } else { |
|
497 log_info(gc, metaspace)(HEAP_CHANGE_FORMAT, |
|
498 HEAP_CHANGE_FORMAT_ARGS("Metaspace", |
|
499 pre_meta_values.used(), |
|
500 pre_meta_values.committed(), |
|
501 meta_values.used(), |
|
502 meta_values.committed())); |
|
503 } |
477 } |
504 } |
478 |
505 |
479 void MetaspaceUtils::print_on(outputStream* out) { |
506 void MetaspaceUtils::print_on(outputStream* out) { |
480 Metaspace::MetadataType nct = Metaspace::NonClassType; |
507 Metaspace::MetadataType nct = Metaspace::NonClassType; |
481 |
508 |
554 } |
581 } |
555 |
582 |
556 // This will print out a basic metaspace usage report but |
583 // This will print out a basic metaspace usage report but |
557 // unlike print_report() is guaranteed not to lock or to walk the CLDG. |
584 // unlike print_report() is guaranteed not to lock or to walk the CLDG. |
558 void MetaspaceUtils::print_basic_report(outputStream* out, size_t scale) { |
585 void MetaspaceUtils::print_basic_report(outputStream* out, size_t scale) { |
|
586 |
|
587 if (!Metaspace::initialized()) { |
|
588 out->print_cr("Metaspace not yet initialized."); |
|
589 return; |
|
590 } |
559 |
591 |
560 out->cr(); |
592 out->cr(); |
561 out->print_cr("Usage:"); |
593 out->print_cr("Usage:"); |
562 |
594 |
563 if (Metaspace::using_class_space()) { |
595 if (Metaspace::using_class_space()) { |
642 out->cr(); |
674 out->cr(); |
643 |
675 |
644 } |
676 } |
645 |
677 |
646 void MetaspaceUtils::print_report(outputStream* out, size_t scale, int flags) { |
678 void MetaspaceUtils::print_report(outputStream* out, size_t scale, int flags) { |
|
679 |
|
680 if (!Metaspace::initialized()) { |
|
681 out->print_cr("Metaspace not yet initialized."); |
|
682 return; |
|
683 } |
647 |
684 |
648 const bool print_loaders = (flags & rf_show_loaders) > 0; |
685 const bool print_loaders = (flags & rf_show_loaders) > 0; |
649 const bool print_classes = (flags & rf_show_classes) > 0; |
686 const bool print_classes = (flags & rf_show_classes) > 0; |
650 const bool print_by_chunktype = (flags & rf_break_down_by_chunktype) > 0; |
687 const bool print_by_chunktype = (flags & rf_break_down_by_chunktype) > 0; |
651 const bool print_by_spacetype = (flags & rf_break_down_by_spacetype) > 0; |
688 const bool print_by_spacetype = (flags & rf_break_down_by_spacetype) > 0; |
930 VirtualSpaceList* Metaspace::_class_space_list = NULL; |
967 VirtualSpaceList* Metaspace::_class_space_list = NULL; |
931 |
968 |
932 ChunkManager* Metaspace::_chunk_manager_metadata = NULL; |
969 ChunkManager* Metaspace::_chunk_manager_metadata = NULL; |
933 ChunkManager* Metaspace::_chunk_manager_class = NULL; |
970 ChunkManager* Metaspace::_chunk_manager_class = NULL; |
934 |
971 |
|
972 bool Metaspace::_initialized = false; |
|
973 |
935 #define VIRTUALSPACEMULTIPLIER 2 |
974 #define VIRTUALSPACEMULTIPLIER 2 |
936 |
975 |
937 #ifdef _LP64 |
976 #ifdef _LP64 |
938 static const uint64_t UnscaledClassSpaceMax = (uint64_t(max_juint) + 1); |
977 static const uint64_t UnscaledClassSpaceMax = (uint64_t(max_juint) + 1); |
939 |
978 |
1219 // metaspace. |
1258 // metaspace. |
1220 MetaspaceShared::initialize_runtime_shared_and_meta_spaces(); |
1259 MetaspaceShared::initialize_runtime_shared_and_meta_spaces(); |
1221 } |
1260 } |
1222 |
1261 |
1223 if (DynamicDumpSharedSpaces && !UseSharedSpaces) { |
1262 if (DynamicDumpSharedSpaces && !UseSharedSpaces) { |
1224 vm_exit_during_initialization("DynamicDumpSharedSpaces not supported when base CDS archive is not loaded", NULL); |
1263 vm_exit_during_initialization("DynamicDumpSharedSpaces is unsupported when base CDS archive is not loaded", NULL); |
1225 } |
1264 } |
1226 |
1265 |
1227 if (!DumpSharedSpaces && !UseSharedSpaces) |
1266 if (!DumpSharedSpaces && !UseSharedSpaces) |
1228 #endif // INCLUDE_CDS |
1267 #endif // INCLUDE_CDS |
1229 { |
1268 { |
1230 #ifdef _LP64 |
1269 #ifdef _LP64 |
1231 if (using_class_space()) { |
1270 if (using_class_space()) { |
1232 char* base = (char*)align_up(Universe::heap()->reserved_region().end(), _reserve_alignment); |
1271 char* base = (char*)align_up(CompressedOops::end(), _reserve_alignment); |
1233 allocate_metaspace_compressed_klass_ptrs(base, 0); |
1272 allocate_metaspace_compressed_klass_ptrs(base, 0); |
1234 } |
1273 } |
1235 #endif // _LP64 |
1274 #endif // _LP64 |
1236 } |
1275 } |
1237 |
1276 |
1256 if (!_space_list->initialization_succeeded()) { |
1295 if (!_space_list->initialization_succeeded()) { |
1257 vm_exit_during_initialization("Unable to setup metadata virtual space list.", NULL); |
1296 vm_exit_during_initialization("Unable to setup metadata virtual space list.", NULL); |
1258 } |
1297 } |
1259 |
1298 |
1260 _tracer = new MetaspaceTracer(); |
1299 _tracer = new MetaspaceTracer(); |
|
1300 |
|
1301 _initialized = true; |
|
1302 |
1261 } |
1303 } |
1262 |
1304 |
1263 void Metaspace::post_initialize() { |
1305 void Metaspace::post_initialize() { |
1264 MetaspaceGC::post_initialize(); |
1306 MetaspaceGC::post_initialize(); |
1265 } |
1307 } |
1586 add_to_statistics_locked(out); |
1628 add_to_statistics_locked(out); |
1587 } |
1629 } |
1588 |
1630 |
1589 /////////////// Unit tests /////////////// |
1631 /////////////// Unit tests /////////////// |
1590 |
1632 |
1591 #ifndef PRODUCT |
|
1592 |
|
1593 class TestMetaspaceUtilsTest : AllStatic { |
|
1594 public: |
|
1595 static void test_reserved() { |
|
1596 size_t reserved = MetaspaceUtils::reserved_bytes(); |
|
1597 |
|
1598 assert(reserved > 0, "assert"); |
|
1599 |
|
1600 size_t committed = MetaspaceUtils::committed_bytes(); |
|
1601 assert(committed <= reserved, "assert"); |
|
1602 |
|
1603 size_t reserved_metadata = MetaspaceUtils::reserved_bytes(Metaspace::NonClassType); |
|
1604 assert(reserved_metadata > 0, "assert"); |
|
1605 assert(reserved_metadata <= reserved, "assert"); |
|
1606 |
|
1607 if (UseCompressedClassPointers) { |
|
1608 size_t reserved_class = MetaspaceUtils::reserved_bytes(Metaspace::ClassType); |
|
1609 assert(reserved_class > 0, "assert"); |
|
1610 assert(reserved_class < reserved, "assert"); |
|
1611 } |
|
1612 } |
|
1613 |
|
1614 static void test_committed() { |
|
1615 size_t committed = MetaspaceUtils::committed_bytes(); |
|
1616 |
|
1617 assert(committed > 0, "assert"); |
|
1618 |
|
1619 size_t reserved = MetaspaceUtils::reserved_bytes(); |
|
1620 assert(committed <= reserved, "assert"); |
|
1621 |
|
1622 size_t committed_metadata = MetaspaceUtils::committed_bytes(Metaspace::NonClassType); |
|
1623 assert(committed_metadata > 0, "assert"); |
|
1624 assert(committed_metadata <= committed, "assert"); |
|
1625 |
|
1626 if (UseCompressedClassPointers) { |
|
1627 size_t committed_class = MetaspaceUtils::committed_bytes(Metaspace::ClassType); |
|
1628 assert(committed_class > 0, "assert"); |
|
1629 assert(committed_class < committed, "assert"); |
|
1630 } |
|
1631 } |
|
1632 |
|
1633 static void test_virtual_space_list_large_chunk() { |
|
1634 VirtualSpaceList* vs_list = new VirtualSpaceList(os::vm_allocation_granularity()); |
|
1635 MutexLocker cl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag); |
|
1636 // A size larger than VirtualSpaceSize (256k) and add one page to make it _not_ be |
|
1637 // vm_allocation_granularity aligned on Windows. |
|
1638 size_t large_size = (size_t)(2*256*K + (os::vm_page_size()/BytesPerWord)); |
|
1639 large_size += (os::vm_page_size()/BytesPerWord); |
|
1640 vs_list->get_new_chunk(large_size, 0); |
|
1641 } |
|
1642 |
|
1643 static void test() { |
|
1644 test_reserved(); |
|
1645 test_committed(); |
|
1646 test_virtual_space_list_large_chunk(); |
|
1647 } |
|
1648 }; |
|
1649 |
|
1650 void TestMetaspaceUtils_test() { |
|
1651 TestMetaspaceUtilsTest::test(); |
|
1652 } |
|
1653 |
|
1654 #endif // !PRODUCT |
|
1655 |
|
1656 struct chunkmanager_statistics_t { |
1633 struct chunkmanager_statistics_t { |
1657 int num_specialized_chunks; |
1634 int num_specialized_chunks; |
1658 int num_small_chunks; |
1635 int num_small_chunks; |
1659 int num_medium_chunks; |
1636 int num_medium_chunks; |
1660 int num_humongous_chunks; |
1637 int num_humongous_chunks; |