Mercurial > hg > truffle
comparison src/share/vm/memory/metaspace.cpp @ 11064:de2d15ce3d4a
8015391: NPG: With -XX:+UseCompressedKlassPointers OOME due to exhausted metadata space could occur when metaspace is almost empty
Summary: Allocate medium chunks for class metaspace when class loader has lots of classes
Reviewed-by: mgerdin, jmasa
author | coleenp |
---|---|
date | Tue, 02 Jul 2013 08:42:37 -0400 |
parents | a1ebd310d5c1 |
children | cedf20e2a655 |
comparison
equal
deleted
inserted
replaced
11028:b3cd8b58b798 | 11064:de2d15ce3d4a |
---|---|
68 enum ChunkSizes { // in words. | 68 enum ChunkSizes { // in words. |
69 ClassSpecializedChunk = 128, | 69 ClassSpecializedChunk = 128, |
70 SpecializedChunk = 128, | 70 SpecializedChunk = 128, |
71 ClassSmallChunk = 256, | 71 ClassSmallChunk = 256, |
72 SmallChunk = 512, | 72 SmallChunk = 512, |
73 ClassMediumChunk = 1 * K, | 73 ClassMediumChunk = 4 * K, |
74 MediumChunk = 8 * K, | 74 MediumChunk = 8 * K, |
75 HumongousChunkGranularity = 8 | 75 HumongousChunkGranularity = 8 |
76 }; | 76 }; |
77 | 77 |
78 static ChunkIndex next_chunk_index(ChunkIndex i) { | 78 static ChunkIndex next_chunk_index(ChunkIndex i) { |
578 VirtualSpaceList* _vs_list; | 578 VirtualSpaceList* _vs_list; |
579 | 579 |
580 // Number of small chunks to allocate to a manager | 580 // Number of small chunks to allocate to a manager |
581 // If class space manager, small chunks are unlimited | 581 // If class space manager, small chunks are unlimited |
582 static uint const _small_chunk_limit; | 582 static uint const _small_chunk_limit; |
583 bool has_small_chunk_limit() { return !vs_list()->is_class(); } | |
584 | 583 |
585 // Sum of all space in allocated chunks | 584 // Sum of all space in allocated chunks |
586 size_t _allocated_blocks_words; | 585 size_t _allocated_blocks_words; |
587 | 586 |
588 // Sum of all allocated chunks | 587 // Sum of all allocated chunks |
1296 return delta_words; | 1295 return delta_words; |
1297 } | 1296 } |
1298 | 1297 |
1299 bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { | 1298 bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { |
1300 | 1299 |
1301 size_t committed_capacity_bytes = MetaspaceAux::allocated_capacity_bytes(); | |
1302 // If the user wants a limit, impose one. | 1300 // If the user wants a limit, impose one. |
1303 size_t max_metaspace_size_bytes = MaxMetaspaceSize; | 1301 // The reason for someone using this flag is to limit reserved space. So |
1304 size_t metaspace_size_bytes = MetaspaceSize; | 1302 // for non-class virtual space, compare against virtual spaces that are reserved. |
1305 if (!FLAG_IS_DEFAULT(MaxMetaspaceSize) && | 1303 // For class virtual space, we only compare against the committed space, not |
1306 MetaspaceAux::reserved_in_bytes() >= MaxMetaspaceSize) { | 1304 // reserved space, because this is a larger space prereserved for compressed |
1307 return false; | 1305 // class pointers. |
1306 if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) { | |
1307 size_t real_allocated = Metaspace::space_list()->virtual_space_total() + | |
1308 MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); | |
1309 if (real_allocated >= MaxMetaspaceSize) { | |
1310 return false; | |
1311 } | |
1308 } | 1312 } |
1309 | 1313 |
1310 // Class virtual space should always be expanded. Call GC for the other | 1314 // Class virtual space should always be expanded. Call GC for the other |
1311 // metadata virtual space. | 1315 // metadata virtual space. |
1312 if (vsl == Metaspace::class_space_list()) return true; | 1316 if (vsl == Metaspace::class_space_list()) return true; |
1316 if (MetaspaceGC::expand_after_GC()) { | 1320 if (MetaspaceGC::expand_after_GC()) { |
1317 return true; | 1321 return true; |
1318 } | 1322 } |
1319 | 1323 |
1320 | 1324 |
1321 | |
1322 // If the capacity is below the minimum capacity, allow the | 1325 // If the capacity is below the minimum capacity, allow the |
1323 // expansion. Also set the high-water-mark (capacity_until_GC) | 1326 // expansion. Also set the high-water-mark (capacity_until_GC) |
1324 // to that minimum capacity so that a GC will not be induced | 1327 // to that minimum capacity so that a GC will not be induced |
1325 // until that minimum capacity is exceeded. | 1328 // until that minimum capacity is exceeded. |
1329 size_t committed_capacity_bytes = MetaspaceAux::allocated_capacity_bytes(); | |
1330 size_t metaspace_size_bytes = MetaspaceSize; | |
1326 if (committed_capacity_bytes < metaspace_size_bytes || | 1331 if (committed_capacity_bytes < metaspace_size_bytes || |
1327 capacity_until_GC() == 0) { | 1332 capacity_until_GC() == 0) { |
1328 set_capacity_until_GC(metaspace_size_bytes); | 1333 set_capacity_until_GC(metaspace_size_bytes); |
1329 return true; | 1334 return true; |
1330 } else { | 1335 } else { |
1864 size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const { | 1869 size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const { |
1865 size_t result = 0; | 1870 size_t result = 0; |
1866 Metachunk* chunk = chunks_in_use(index); | 1871 Metachunk* chunk = chunks_in_use(index); |
1867 // Count the free space in all the chunk but not the | 1872 // Count the free space in all the chunk but not the |
1868 // current chunk from which allocations are still being done. | 1873 // current chunk from which allocations are still being done. |
1869 if (chunk != NULL) { | 1874 while (chunk != NULL) { |
1870 Metachunk* prev = chunk; | 1875 if (chunk != current_chunk()) { |
1871 while (chunk != NULL && chunk != current_chunk()) { | |
1872 result += chunk->free_word_size(); | 1876 result += chunk->free_word_size(); |
1873 prev = chunk; | 1877 } |
1874 chunk = chunk->next(); | 1878 chunk = chunk->next(); |
1875 } | |
1876 } | 1879 } |
1877 return result; | 1880 return result; |
1878 } | 1881 } |
1879 | 1882 |
1880 size_t SpaceManager::sum_capacity_in_chunks_in_use() const { | 1883 size_t SpaceManager::sum_capacity_in_chunks_in_use() const { |
1959 // _small_chunk_limit small chunks can be allocated but | 1962 // _small_chunk_limit small chunks can be allocated but |
1960 // once a medium chunk has been allocated, no more small | 1963 // once a medium chunk has been allocated, no more small |
1961 // chunks will be allocated. | 1964 // chunks will be allocated. |
1962 size_t chunk_word_size; | 1965 size_t chunk_word_size; |
1963 if (chunks_in_use(MediumIndex) == NULL && | 1966 if (chunks_in_use(MediumIndex) == NULL && |
1964 (!has_small_chunk_limit() || | 1967 sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) { |
1965 sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit)) { | |
1966 chunk_word_size = (size_t) small_chunk_size(); | 1968 chunk_word_size = (size_t) small_chunk_size(); |
1967 if (word_size + Metachunk::overhead() > small_chunk_size()) { | 1969 if (word_size + Metachunk::overhead() > small_chunk_size()) { |
1968 chunk_word_size = medium_chunk_size(); | 1970 chunk_word_size = medium_chunk_size(); |
1969 } | 1971 } |
1970 } else { | 1972 } else { |
2669 } | 2671 } |
2670 | 2672 |
2671 // Print total fragmentation for class and data metaspaces separately | 2673 // Print total fragmentation for class and data metaspaces separately |
2672 void MetaspaceAux::print_waste(outputStream* out) { | 2674 void MetaspaceAux::print_waste(outputStream* out) { |
2673 | 2675 |
2674 size_t specialized_waste = 0, small_waste = 0, medium_waste = 0, large_waste = 0; | 2676 size_t specialized_waste = 0, small_waste = 0, medium_waste = 0; |
2675 size_t specialized_count = 0, small_count = 0, medium_count = 0, large_count = 0; | 2677 size_t specialized_count = 0, small_count = 0, medium_count = 0, humongous_count = 0; |
2676 size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0, cls_large_waste = 0; | 2678 size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0; |
2677 size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_large_count = 0; | 2679 size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_humongous_count = 0; |
2678 | 2680 |
2679 ClassLoaderDataGraphMetaspaceIterator iter; | 2681 ClassLoaderDataGraphMetaspaceIterator iter; |
2680 while (iter.repeat()) { | 2682 while (iter.repeat()) { |
2681 Metaspace* msp = iter.get_next(); | 2683 Metaspace* msp = iter.get_next(); |
2682 if (msp != NULL) { | 2684 if (msp != NULL) { |
2684 specialized_count += msp->vsm()->sum_count_in_chunks_in_use(SpecializedIndex); | 2686 specialized_count += msp->vsm()->sum_count_in_chunks_in_use(SpecializedIndex); |
2685 small_waste += msp->vsm()->sum_waste_in_chunks_in_use(SmallIndex); | 2687 small_waste += msp->vsm()->sum_waste_in_chunks_in_use(SmallIndex); |
2686 small_count += msp->vsm()->sum_count_in_chunks_in_use(SmallIndex); | 2688 small_count += msp->vsm()->sum_count_in_chunks_in_use(SmallIndex); |
2687 medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex); | 2689 medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex); |
2688 medium_count += msp->vsm()->sum_count_in_chunks_in_use(MediumIndex); | 2690 medium_count += msp->vsm()->sum_count_in_chunks_in_use(MediumIndex); |
2689 large_waste += msp->vsm()->sum_waste_in_chunks_in_use(HumongousIndex); | 2691 humongous_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex); |
2690 large_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex); | |
2691 | 2692 |
2692 cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex); | 2693 cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex); |
2693 cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex); | 2694 cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex); |
2694 cls_small_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SmallIndex); | 2695 cls_small_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SmallIndex); |
2695 cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex); | 2696 cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex); |
2696 cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex); | 2697 cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex); |
2697 cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex); | 2698 cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex); |
2698 cls_large_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(HumongousIndex); | 2699 cls_humongous_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex); |
2699 cls_large_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex); | |
2700 } | 2700 } |
2701 } | 2701 } |
2702 out->print_cr("Total fragmentation waste (words) doesn't count free space"); | 2702 out->print_cr("Total fragmentation waste (words) doesn't count free space"); |
2703 out->print_cr(" data: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " | 2703 out->print_cr(" data: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " |
2704 SIZE_FORMAT " small(s) " SIZE_FORMAT ", " | 2704 SIZE_FORMAT " small(s) " SIZE_FORMAT ", " |
2705 SIZE_FORMAT " medium(s) " SIZE_FORMAT, | 2705 SIZE_FORMAT " medium(s) " SIZE_FORMAT ", " |
2706 "large count " SIZE_FORMAT, | |
2706 specialized_count, specialized_waste, small_count, | 2707 specialized_count, specialized_waste, small_count, |
2707 small_waste, medium_count, medium_waste); | 2708 small_waste, medium_count, medium_waste, humongous_count); |
2708 out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " | 2709 out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " |
2709 SIZE_FORMAT " small(s) " SIZE_FORMAT, | 2710 SIZE_FORMAT " small(s) " SIZE_FORMAT ", " |
2711 SIZE_FORMAT " medium(s) " SIZE_FORMAT ", " | |
2712 "large count " SIZE_FORMAT, | |
2710 cls_specialized_count, cls_specialized_waste, | 2713 cls_specialized_count, cls_specialized_waste, |
2711 cls_small_count, cls_small_waste); | 2714 cls_small_count, cls_small_waste, |
2715 cls_medium_count, cls_medium_waste, cls_humongous_count); | |
2712 } | 2716 } |
2713 | 2717 |
2714 // Dump global metaspace things from the end of ClassLoaderDataGraph | 2718 // Dump global metaspace things from the end of ClassLoaderDataGraph |
2715 void MetaspaceAux::dump(outputStream* out) { | 2719 void MetaspaceAux::dump(outputStream* out) { |
2716 out->print_cr("All Metaspace:"); | 2720 out->print_cr("All Metaspace:"); |
3047 // If result is still null, we are out of memory. | 3051 // If result is still null, we are out of memory. |
3048 if (result == NULL) { | 3052 if (result == NULL) { |
3049 if (Verbose && TraceMetadataChunkAllocation) { | 3053 if (Verbose && TraceMetadataChunkAllocation) { |
3050 gclog_or_tty->print_cr("Metaspace allocation failed for size " | 3054 gclog_or_tty->print_cr("Metaspace allocation failed for size " |
3051 SIZE_FORMAT, word_size); | 3055 SIZE_FORMAT, word_size); |
3052 if (loader_data->metaspace_or_null() != NULL) loader_data->metaspace_or_null()->dump(gclog_or_tty); | 3056 if (loader_data->metaspace_or_null() != NULL) loader_data->dump(gclog_or_tty); |
3053 MetaspaceAux::dump(gclog_or_tty); | 3057 MetaspaceAux::dump(gclog_or_tty); |
3054 } | 3058 } |
3055 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support | 3059 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support |
3056 report_java_out_of_memory("Metadata space"); | 3060 const char* space_string = (mdtype == ClassType) ? "Class Metadata space" : |
3061 "Metadata space"; | |
3062 report_java_out_of_memory(space_string); | |
3057 | 3063 |
3058 if (JvmtiExport::should_post_resource_exhausted()) { | 3064 if (JvmtiExport::should_post_resource_exhausted()) { |
3059 JvmtiExport::post_resource_exhausted( | 3065 JvmtiExport::post_resource_exhausted( |
3060 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, | 3066 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, |
3061 "Metadata space"); | 3067 space_string); |
3062 } | 3068 } |
3063 THROW_OOP_0(Universe::out_of_memory_error_perm_gen()); | 3069 if (mdtype == ClassType) { |
3070 THROW_OOP_0(Universe::out_of_memory_error_class_metaspace()); | |
3071 } else { | |
3072 THROW_OOP_0(Universe::out_of_memory_error_metaspace()); | |
3073 } | |
3064 } | 3074 } |
3065 } | 3075 } |
3066 return Metablock::initialize(result, word_size); | 3076 return Metablock::initialize(result, word_size); |
3067 } | 3077 } |
3068 | 3078 |