Mercurial > hg > graal-jvmci-8
comparison src/share/vm/memory/metaspace.cpp @ 23063:57d4971ff1df
8086111: BACKOUT - metaspace/shrink_grow/CompressedClassSpaceSize fails with OOM: Compressed class space
Reviewed-by: brutisso
author | jwilhelm |
---|---|
date | Tue, 09 Jun 2015 20:10:29 +0200 |
parents | afc7b3416dc6 |
children | dd9cc155639c |
comparison
equal
deleted
inserted
replaced
23060:91a1be057e0a | 23063:57d4971ff1df |
---|---|
620 // are done from the current chunk. The list is used for deallocating | 620 // are done from the current chunk. The list is used for deallocating |
621 // chunks when the SpaceManager is freed. | 621 // chunks when the SpaceManager is freed. |
622 Metachunk* _chunks_in_use[NumberOfInUseLists]; | 622 Metachunk* _chunks_in_use[NumberOfInUseLists]; |
623 Metachunk* _current_chunk; | 623 Metachunk* _current_chunk; |
624 | 624 |
625 // Maximum number of small chunks to allocate to a SpaceManager | 625 // Number of small chunks to allocate to a manager |
626 // If class space manager, small chunks are unlimited | |
626 static uint const _small_chunk_limit; | 627 static uint const _small_chunk_limit; |
627 | 628 |
628 // Sum of all space in allocated chunks | 629 // Sum of all space in allocated chunks |
629 size_t _allocated_blocks_words; | 630 size_t _allocated_blocks_words; |
630 | 631 |
734 Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words); | 735 Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words); |
735 | 736 |
736 // Block allocation and deallocation. | 737 // Block allocation and deallocation. |
737 // Allocates a block from the current chunk | 738 // Allocates a block from the current chunk |
738 MetaWord* allocate(size_t word_size); | 739 MetaWord* allocate(size_t word_size); |
739 // Allocates a block from a small chunk | |
740 MetaWord* get_small_chunk_and_allocate(size_t word_size); | |
741 | 740 |
742 // Helper for allocations | 741 // Helper for allocations |
743 MetaWord* allocate_work(size_t word_size); | 742 MetaWord* allocate_work(size_t word_size); |
744 | 743 |
745 // Returns a block to the per manager freelist | 744 // Returns a block to the per manager freelist |
2030 } | 2029 } |
2031 | 2030 |
2032 size_t SpaceManager::calc_chunk_size(size_t word_size) { | 2031 size_t SpaceManager::calc_chunk_size(size_t word_size) { |
2033 | 2032 |
2034 // Decide between a small chunk and a medium chunk. Up to | 2033 // Decide between a small chunk and a medium chunk. Up to |
2035 // _small_chunk_limit small chunks can be allocated. | 2034 // _small_chunk_limit small chunks can be allocated but |
2036 // After that a medium chunk is preferred. | 2035 // once a medium chunk has been allocated, no more small |
2036 // chunks will be allocated. | |
2037 size_t chunk_word_size; | 2037 size_t chunk_word_size; |
2038 if (chunks_in_use(MediumIndex) == NULL && | 2038 if (chunks_in_use(MediumIndex) == NULL && |
2039 sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) { | 2039 sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) { |
2040 chunk_word_size = (size_t) small_chunk_size(); | 2040 chunk_word_size = (size_t) small_chunk_size(); |
2041 if (word_size + Metachunk::overhead() > small_chunk_size()) { | 2041 if (word_size + Metachunk::overhead() > small_chunk_size()) { |
2099 " words " SIZE_FORMAT " words used " SIZE_FORMAT | 2099 " words " SIZE_FORMAT " words used " SIZE_FORMAT |
2100 " words left", | 2100 " words left", |
2101 word_size, words_used, words_left); | 2101 word_size, words_used, words_left); |
2102 } | 2102 } |
2103 | 2103 |
2104 // Get another chunk | 2104 // Get another chunk out of the virtual space |
2105 size_t grow_chunks_by_words = calc_chunk_size(word_size); | 2105 size_t grow_chunks_by_words = calc_chunk_size(word_size); |
2106 Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words); | 2106 Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words); |
2107 | 2107 |
2108 MetaWord* mem = NULL; | 2108 MetaWord* mem = NULL; |
2109 | 2109 |
2428 gclog_or_tty->print_cr(" new humongous chunk word size " | 2428 gclog_or_tty->print_cr(" new humongous chunk word size " |
2429 PTR_FORMAT, next->word_size()); | 2429 PTR_FORMAT, next->word_size()); |
2430 } | 2430 } |
2431 | 2431 |
2432 return next; | 2432 return next; |
2433 } | |
2434 | |
2435 /* | |
2436 * The policy is to allocate up to _small_chunk_limit small chunks | |
2437 * after which only medium chunks are allocated. This is done to | |
2438 * reduce fragmentation. In some cases, this can result in a lot | |
2439 * of small chunks being allocated to the point where it's not | |
2440 * possible to expand. If this happens, there may be no medium chunks | |
2441 * available and OOME would be thrown. Instead of doing that, | |
2442 * if the allocation request size fits in a small chunk, an attempt | |
2443 * will be made to allocate a small chunk. | |
2444 */ | |
2445 MetaWord* SpaceManager::get_small_chunk_and_allocate(size_t word_size) { | |
2446 if (word_size + Metachunk::overhead() > small_chunk_size()) { | |
2447 return NULL; | |
2448 } | |
2449 | |
2450 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); | |
2451 MutexLockerEx cl1(expand_lock(), Mutex::_no_safepoint_check_flag); | |
2452 | |
2453 Metachunk* chunk = chunk_manager()->chunk_freelist_allocate(small_chunk_size()); | |
2454 | |
2455 MetaWord* mem = NULL; | |
2456 | |
2457 if (chunk != NULL) { | |
2458 // Add chunk to the in-use chunk list and do an allocation from it. | |
2459 // Add to this manager's list of chunks in use. | |
2460 add_chunk(chunk, false); | |
2461 mem = chunk->allocate(word_size); | |
2462 | |
2463 inc_used_metrics(word_size); | |
2464 | |
2465 // Track metaspace memory usage statistic. | |
2466 track_metaspace_memory_usage(); | |
2467 } | |
2468 | |
2469 return mem; | |
2470 } | 2433 } |
2471 | 2434 |
2472 MetaWord* SpaceManager::allocate(size_t word_size) { | 2435 MetaWord* SpaceManager::allocate(size_t word_size) { |
2473 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); | 2436 MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); |
2474 | 2437 |
3546 loader_data, word_size, mdtype); | 3509 loader_data, word_size, mdtype); |
3547 } | 3510 } |
3548 } | 3511 } |
3549 | 3512 |
3550 if (result == NULL) { | 3513 if (result == NULL) { |
3551 SpaceManager* sm; | 3514 report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL); |
3552 if (is_class_space_allocation(mdtype)) { | |
3553 sm = loader_data->metaspace_non_null()->class_vsm(); | |
3554 } else { | |
3555 sm = loader_data->metaspace_non_null()->vsm(); | |
3556 } | |
3557 | |
3558 result = sm->get_small_chunk_and_allocate(word_size); | |
3559 | |
3560 if (result == NULL) { | |
3561 report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL); | |
3562 } | |
3563 } | 3515 } |
3564 | 3516 |
3565 // Zero initialize. | 3517 // Zero initialize. |
3566 Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0); | 3518 Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0); |
3567 | 3519 |