2030 st->print_cr("total in block free lists " SIZE_FORMAT, |
2035 st->print_cr("total in block free lists " SIZE_FORMAT, |
2031 block_freelists()->total_size()); |
2036 block_freelists()->total_size()); |
2032 } |
2037 } |
2033 } |
2038 } |
2034 |
2039 |
2035 SpaceManager::SpaceManager(Mutex* lock, |
2040 SpaceManager::SpaceManager(Metaspace::MetadataType mdtype, |
|
2041 Mutex* lock, |
2036 VirtualSpaceList* vs_list) : |
2042 VirtualSpaceList* vs_list) : |
2037 _vs_list(vs_list), |
2043 _vs_list(vs_list), |
|
2044 _mdtype(mdtype), |
2038 _allocated_blocks_words(0), |
2045 _allocated_blocks_words(0), |
2039 _allocated_chunks_words(0), |
2046 _allocated_chunks_words(0), |
2040 _allocated_chunks_count(0), |
2047 _allocated_chunks_count(0), |
2041 _lock(lock) |
2048 _lock(lock) |
2042 { |
2049 { |
2048 // Total of allocated Metachunks and allocated Metachunks count |
2055 // Total of allocated Metachunks and allocated Metachunks count |
2049 // for each SpaceManager |
2056 // for each SpaceManager |
2050 _allocated_chunks_words = _allocated_chunks_words + words; |
2057 _allocated_chunks_words = _allocated_chunks_words + words; |
2051 _allocated_chunks_count++; |
2058 _allocated_chunks_count++; |
2052 // Global total of capacity in allocated Metachunks |
2059 // Global total of capacity in allocated Metachunks |
2053 MetaspaceAux::inc_capacity(words); |
2060 MetaspaceAux::inc_capacity(mdtype(), words); |
2054 // Global total of allocated Metablocks. |
2061 // Global total of allocated Metablocks. |
2055 // used_words_slow() includes the overhead in each |
2062 // used_words_slow() includes the overhead in each |
2056 // Metachunk so include it in the used when the |
2063 // Metachunk so include it in the used when the |
2057 // Metachunk is first added (so only added once per |
2064 // Metachunk is first added (so only added once per |
2058 // Metachunk). |
2065 // Metachunk). |
2059 MetaspaceAux::inc_used(Metachunk::overhead()); |
2066 MetaspaceAux::inc_used(mdtype(), Metachunk::overhead()); |
2060 } |
2067 } |
2061 |
2068 |
2062 void SpaceManager::inc_used_metrics(size_t words) { |
2069 void SpaceManager::inc_used_metrics(size_t words) { |
2063 // Add to the per SpaceManager total |
2070 // Add to the per SpaceManager total |
2064 Atomic::add_ptr(words, &_allocated_blocks_words); |
2071 Atomic::add_ptr(words, &_allocated_blocks_words); |
2065 // Add to the global total |
2072 // Add to the global total |
2066 MetaspaceAux::inc_used(words); |
2073 MetaspaceAux::inc_used(mdtype(), words); |
2067 } |
2074 } |
2068 |
2075 |
2069 void SpaceManager::dec_total_from_size_metrics() { |
2076 void SpaceManager::dec_total_from_size_metrics() { |
2070 MetaspaceAux::dec_capacity(allocated_chunks_words()); |
2077 MetaspaceAux::dec_capacity(mdtype(), allocated_chunks_words()); |
2071 MetaspaceAux::dec_used(allocated_blocks_words()); |
2078 MetaspaceAux::dec_used(mdtype(), allocated_blocks_words()); |
2072 // Also deduct the overhead per Metachunk |
2079 // Also deduct the overhead per Metachunk |
2073 MetaspaceAux::dec_used(allocated_chunks_count() * Metachunk::overhead()); |
2080 MetaspaceAux::dec_used(mdtype(), allocated_chunks_count() * Metachunk::overhead()); |
2074 } |
2081 } |
2075 |
2082 |
2076 void SpaceManager::initialize() { |
2083 void SpaceManager::initialize() { |
2077 Metadebug::init_allocation_fail_alot_count(); |
2084 Metadebug::init_allocation_fail_alot_count(); |
2078 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { |
2085 for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { |
2482 result = result + Metaspace::space_list()->free_bytes(); |
2489 result = result + Metaspace::space_list()->free_bytes(); |
2483 } |
2490 } |
2484 return result; |
2491 return result; |
2485 } |
2492 } |
2486 |
2493 |
2487 void MetaspaceAux::dec_capacity(size_t words) { |
2494 void MetaspaceAux::dec_capacity(Metaspace::MetadataType mdtype, size_t words) { |
2488 assert_lock_strong(SpaceManager::expand_lock()); |
2495 assert_lock_strong(SpaceManager::expand_lock()); |
2489 assert(words <= _allocated_capacity_words, |
2496 assert(words <= allocated_capacity_words(mdtype), |
2490 err_msg("About to decrement below 0: words " SIZE_FORMAT |
2497 err_msg("About to decrement below 0: words " SIZE_FORMAT |
2491 " is greater than _allocated_capacity_words " SIZE_FORMAT, |
2498 " is greater than _allocated_capacity_words[%u] " SIZE_FORMAT, |
2492 words, _allocated_capacity_words)); |
2499 words, mdtype, allocated_capacity_words(mdtype))); |
2493 _allocated_capacity_words = _allocated_capacity_words - words; |
2500 _allocated_capacity_words[mdtype] -= words; |
2494 } |
2501 } |
2495 |
2502 |
2496 void MetaspaceAux::inc_capacity(size_t words) { |
2503 void MetaspaceAux::inc_capacity(Metaspace::MetadataType mdtype, size_t words) { |
2497 assert_lock_strong(SpaceManager::expand_lock()); |
2504 assert_lock_strong(SpaceManager::expand_lock()); |
2498 // Needs to be atomic |
2505 // Needs to be atomic |
2499 _allocated_capacity_words = _allocated_capacity_words + words; |
2506 _allocated_capacity_words[mdtype] += words; |
2500 } |
2507 } |
2501 |
2508 |
2502 void MetaspaceAux::dec_used(size_t words) { |
2509 void MetaspaceAux::dec_used(Metaspace::MetadataType mdtype, size_t words) { |
2503 assert(words <= _allocated_used_words, |
2510 assert(words <= allocated_used_words(mdtype), |
2504 err_msg("About to decrement below 0: words " SIZE_FORMAT |
2511 err_msg("About to decrement below 0: words " SIZE_FORMAT |
2505 " is greater than _allocated_used_words " SIZE_FORMAT, |
2512 " is greater than _allocated_used_words[%u] " SIZE_FORMAT, |
2506 words, _allocated_used_words)); |
2513 words, mdtype, allocated_used_words(mdtype))); |
2507 // For CMS deallocation of the Metaspaces occurs during the |
2514 // For CMS deallocation of the Metaspaces occurs during the |
2508 // sweep which is a concurrent phase. Protection by the expand_lock() |
2515 // sweep which is a concurrent phase. Protection by the expand_lock() |
2509 // is not enough since allocation is on a per Metaspace basis |
2516 // is not enough since allocation is on a per Metaspace basis |
2510 // and protected by the Metaspace lock. |
2517 // and protected by the Metaspace lock. |
2511 jlong minus_words = (jlong) - (jlong) words; |
2518 jlong minus_words = (jlong) - (jlong) words; |
2512 Atomic::add_ptr(minus_words, &_allocated_used_words); |
2519 Atomic::add_ptr(minus_words, &_allocated_used_words[mdtype]); |
2513 } |
2520 } |
2514 |
2521 |
2515 void MetaspaceAux::inc_used(size_t words) { |
2522 void MetaspaceAux::inc_used(Metaspace::MetadataType mdtype, size_t words) { |
2516 // _allocated_used_words tracks allocations for |
2523 // _allocated_used_words tracks allocations for |
2517 // each piece of metadata. Those allocations are |
2524 // each piece of metadata. Those allocations are |
2518 // generally done concurrently by different application |
2525 // generally done concurrently by different application |
2519 // threads so must be done atomically. |
2526 // threads so must be done atomically. |
2520 Atomic::add_ptr(words, &_allocated_used_words); |
2527 Atomic::add_ptr(words, &_allocated_used_words[mdtype]); |
2521 } |
2528 } |
2522 |
2529 |
2523 size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) { |
2530 size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) { |
2524 size_t used = 0; |
2531 size_t used = 0; |
2525 ClassLoaderDataGraphMetaspaceIterator iter; |
2532 ClassLoaderDataGraphMetaspaceIterator iter; |
2617 |
2624 |
2618 out->print_cr(" Metaspace total " |
2625 out->print_cr(" Metaspace total " |
2619 SIZE_FORMAT "K, used " SIZE_FORMAT "K," |
2626 SIZE_FORMAT "K, used " SIZE_FORMAT "K," |
2620 " reserved " SIZE_FORMAT "K", |
2627 " reserved " SIZE_FORMAT "K", |
2621 allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_in_bytes()/K); |
2628 allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_in_bytes()/K); |
2622 #if 0 |
2629 |
2623 // The calls to capacity_bytes_slow() and used_bytes_slow() cause |
2630 out->print_cr(" data space " |
2624 // lock ordering assertion failures with some collectors. Do |
2631 SIZE_FORMAT "K, used " SIZE_FORMAT "K," |
2625 // not include this code until the lock ordering is fixed. |
2632 " reserved " SIZE_FORMAT "K", |
2626 if (PrintGCDetails && Verbose) { |
2633 allocated_capacity_bytes(nct)/K, |
2627 out->print_cr(" data space " |
2634 allocated_used_bytes(nct)/K, |
2628 SIZE_FORMAT "K, used " SIZE_FORMAT "K," |
2635 reserved_in_bytes(nct)/K); |
2629 " reserved " SIZE_FORMAT "K", |
2636 out->print_cr(" class space " |
2630 capacity_bytes_slow(nct)/K, used_bytes_slow(nct)/K, reserved_in_bytes(nct)/K); |
2637 SIZE_FORMAT "K, used " SIZE_FORMAT "K," |
2631 out->print_cr(" class space " |
2638 " reserved " SIZE_FORMAT "K", |
2632 SIZE_FORMAT "K, used " SIZE_FORMAT "K," |
2639 allocated_capacity_bytes(ct)/K, |
2633 " reserved " SIZE_FORMAT "K", |
2640 allocated_used_bytes(ct)/K, |
2634 capacity_bytes_slow(ct)/K, used_bytes_slow(ct)/K, reserved_in_bytes(ct)/K); |
2641 reserved_in_bytes(ct)/K); |
2635 } |
|
2636 #endif |
|
2637 } |
2642 } |
2638 |
2643 |
2639 // Print information for class space and data space separately. |
2644 // Print information for class space and data space separately. |
2640 // This is almost the same as above. |
2645 // This is almost the same as above. |
2641 void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) { |
2646 void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) { |
2715 } |
2720 } |
2716 |
2721 |
2717 void MetaspaceAux::verify_capacity() { |
2722 void MetaspaceAux::verify_capacity() { |
2718 #ifdef ASSERT |
2723 #ifdef ASSERT |
2719 size_t running_sum_capacity_bytes = allocated_capacity_bytes(); |
2724 size_t running_sum_capacity_bytes = allocated_capacity_bytes(); |
2720 // For purposes of the running sum of used, verify against capacity |
2725 // For purposes of the running sum of capacity, verify against capacity |
2721 size_t capacity_in_use_bytes = capacity_bytes_slow(); |
2726 size_t capacity_in_use_bytes = capacity_bytes_slow(); |
2722 assert(running_sum_capacity_bytes == capacity_in_use_bytes, |
2727 assert(running_sum_capacity_bytes == capacity_in_use_bytes, |
2723 err_msg("allocated_capacity_words() * BytesPerWord " SIZE_FORMAT |
2728 err_msg("allocated_capacity_words() * BytesPerWord " SIZE_FORMAT |
2724 " capacity_bytes_slow()" SIZE_FORMAT, |
2729 " capacity_bytes_slow()" SIZE_FORMAT, |
2725 running_sum_capacity_bytes, capacity_in_use_bytes)); |
2730 running_sum_capacity_bytes, capacity_in_use_bytes)); |
|
2731 for (Metaspace::MetadataType i = Metaspace::ClassType; |
|
2732 i < Metaspace:: MetadataTypeCount; |
|
2733 i = (Metaspace::MetadataType)(i + 1)) { |
|
2734 size_t capacity_in_use_bytes = capacity_bytes_slow(i); |
|
2735 assert(allocated_capacity_bytes(i) == capacity_in_use_bytes, |
|
2736 err_msg("allocated_capacity_bytes(%u) " SIZE_FORMAT |
|
2737 " capacity_bytes_slow(%u)" SIZE_FORMAT, |
|
2738 i, allocated_capacity_bytes(i), i, capacity_in_use_bytes)); |
|
2739 } |
2726 #endif |
2740 #endif |
2727 } |
2741 } |
2728 |
2742 |
2729 void MetaspaceAux::verify_used() { |
2743 void MetaspaceAux::verify_used() { |
2730 #ifdef ASSERT |
2744 #ifdef ASSERT |
2731 size_t running_sum_used_bytes = allocated_used_bytes(); |
2745 size_t running_sum_used_bytes = allocated_used_bytes(); |
2732 // For purposes of the running sum of used, verify against capacity |
2746 // For purposes of the running sum of used, verify against used |
2733 size_t used_in_use_bytes = used_bytes_slow(); |
2747 size_t used_in_use_bytes = used_bytes_slow(); |
2734 assert(allocated_used_bytes() == used_in_use_bytes, |
2748 assert(allocated_used_bytes() == used_in_use_bytes, |
2735 err_msg("allocated_used_bytes() " SIZE_FORMAT |
2749 err_msg("allocated_used_bytes() " SIZE_FORMAT |
2736 " used_bytes_slow()()" SIZE_FORMAT, |
2750 " used_bytes_slow()" SIZE_FORMAT, |
2737 allocated_used_bytes(), used_in_use_bytes)); |
2751 allocated_used_bytes(), used_in_use_bytes)); |
|
2752 for (Metaspace::MetadataType i = Metaspace::ClassType; |
|
2753 i < Metaspace:: MetadataTypeCount; |
|
2754 i = (Metaspace::MetadataType)(i + 1)) { |
|
2755 size_t used_in_use_bytes = used_bytes_slow(i); |
|
2756 assert(allocated_used_bytes(i) == used_in_use_bytes, |
|
2757 err_msg("allocated_used_bytes(%u) " SIZE_FORMAT |
|
2758 " used_bytes_slow(%u)" SIZE_FORMAT, |
|
2759 i, allocated_used_bytes(i), i, used_in_use_bytes)); |
|
2760 } |
2738 #endif |
2761 #endif |
2739 } |
2762 } |
2740 |
2763 |
2741 void MetaspaceAux::verify_metrics() { |
2764 void MetaspaceAux::verify_metrics() { |
2742 verify_capacity(); |
2765 verify_capacity(); |
2847 |
2870 |
2848 assert(class_space_list() != NULL, |
2871 assert(class_space_list() != NULL, |
2849 "Class VirtualSpaceList has not been initialized"); |
2872 "Class VirtualSpaceList has not been initialized"); |
2850 |
2873 |
2851 // Allocate SpaceManager for classes. |
2874 // Allocate SpaceManager for classes. |
2852 _class_vsm = new SpaceManager(lock, class_space_list()); |
2875 _class_vsm = new SpaceManager(Metaspace::ClassType, lock, class_space_list()); |
2853 if (_class_vsm == NULL) { |
2876 if (_class_vsm == NULL) { |
2854 return; |
2877 return; |
2855 } |
2878 } |
2856 |
2879 |
2857 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); |
2880 MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); |