1.1 --- a/src/share/vm/memory/metaspace.cpp Wed Jun 03 14:22:57 2015 +0200 1.2 +++ b/src/share/vm/memory/metaspace.cpp Tue Jun 02 10:09:08 2015 -0400 1.3 @@ -622,8 +622,7 @@ 1.4 Metachunk* _chunks_in_use[NumberOfInUseLists]; 1.5 Metachunk* _current_chunk; 1.6 1.7 - // Number of small chunks to allocate to a manager 1.8 - // If class space manager, small chunks are unlimited 1.9 + // Maximum number of small chunks to allocate to a SpaceManager 1.10 static uint const _small_chunk_limit; 1.11 1.12 // Sum of all space in allocated chunks 1.13 @@ -737,6 +736,8 @@ 1.14 // Block allocation and deallocation. 1.15 // Allocates a block from the current chunk 1.16 MetaWord* allocate(size_t word_size); 1.17 + // Allocates a block from a small chunk 1.18 + MetaWord* get_small_chunk_and_allocate(size_t word_size); 1.19 1.20 // Helper for allocations 1.21 MetaWord* allocate_work(size_t word_size); 1.22 @@ -2031,9 +2032,8 @@ 1.23 size_t SpaceManager::calc_chunk_size(size_t word_size) { 1.24 1.25 // Decide between a small chunk and a medium chunk. Up to 1.26 - // _small_chunk_limit small chunks can be allocated but 1.27 - // once a medium chunk has been allocated, no more small 1.28 - // chunks will be allocated. 1.29 + // _small_chunk_limit small chunks can be allocated. 1.30 + // After that a medium chunk is preferred. 1.31 size_t chunk_word_size; 1.32 if (chunks_in_use(MediumIndex) == NULL && 1.33 sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) { 1.34 @@ -2101,7 +2101,7 @@ 1.35 word_size, words_used, words_left); 1.36 } 1.37 1.38 - // Get another chunk out of the virtual space 1.39 + // Get another chunk 1.40 size_t grow_chunks_by_words = calc_chunk_size(word_size); 1.41 Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words); 1.42 1.43 @@ -2432,6 +2432,43 @@ 1.44 return next; 1.45 } 1.46 1.47 +/* 1.48 + * The policy is to allocate up to _small_chunk_limit small chunks 1.49 + * after which only medium chunks are allocated. This is done to 1.50 + * reduce fragmentation. In some cases, this can result in a lot 1.51 + * of small chunks being allocated to the point where it's not 1.52 + * possible to expand. If this happens, there may be no medium chunks 1.53 + * available and OOME would be thrown. Instead of doing that, 1.54 + * if the allocation request size fits in a small chunk, an attempt 1.55 + * will be made to allocate a small chunk. 1.56 + */ 1.57 +MetaWord* SpaceManager::get_small_chunk_and_allocate(size_t word_size) { 1.58 + if (word_size + Metachunk::overhead() > small_chunk_size()) { 1.59 + return NULL; 1.60 + } 1.61 + 1.62 + MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 1.63 + MutexLockerEx cl1(expand_lock(), Mutex::_no_safepoint_check_flag); 1.64 + 1.65 + Metachunk* chunk = chunk_manager()->chunk_freelist_allocate(small_chunk_size()); 1.66 + 1.67 + MetaWord* mem = NULL; 1.68 + 1.69 + if (chunk != NULL) { 1.70 + // Add chunk to the in-use chunk list and do an allocation from it. 1.71 + // Add to this manager's list of chunks in use. 1.72 + add_chunk(chunk, false); 1.73 + mem = chunk->allocate(word_size); 1.74 + 1.75 + inc_used_metrics(word_size); 1.76 + 1.77 + // Track metaspace memory usage statistic. 1.78 + track_metaspace_memory_usage(); 1.79 + } 1.80 + 1.81 + return mem; 1.82 +} 1.83 + 1.84 MetaWord* SpaceManager::allocate(size_t word_size) { 1.85 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); 1.86 1.87 @@ -3511,7 +3548,18 @@ 1.88 } 1.89 1.90 if (result == NULL) { 1.91 - report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL); 1.92 + SpaceManager* sm; 1.93 + if (is_class_space_allocation(mdtype)) { 1.94 + sm = loader_data->metaspace_non_null()->class_vsm(); 1.95 + } else { 1.96 + sm = loader_data->metaspace_non_null()->vsm(); 1.97 + } 1.98 + 1.99 + result = sm->get_small_chunk_and_allocate(word_size); 1.100 + 1.101 + if (result == NULL) { 1.102 + report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL); 1.103 + } 1.104 } 1.105 1.106 // Zero initialize.