mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
8009561: NPG: Metaspace fragmentation when retiring a Metachunk
Use best-fit block-splitting freelist allocation from the block freelist. Reviewed-by: jmasa, stefank
This commit is contained in:
parent
86624d96d7
commit
1d97871624
1 changed files with 32 additions and 3 deletions
|
@ -51,7 +51,7 @@ const bool metaspace_slow_verify = false;
|
|||
// Parameters for stress mode testing
|
||||
const uint metadata_deallocate_a_lot_block = 10;
|
||||
const uint metadata_deallocate_a_lock_chunk = 3;
|
||||
size_t const allocation_from_dictionary_limit = 64 * K;
|
||||
size_t const allocation_from_dictionary_limit = 4 * K;
|
||||
|
||||
MetaWord* last_allocated = 0;
|
||||
|
||||
|
@ -228,6 +228,10 @@ class BlockFreelist VALUE_OBJ_CLASS_SPEC {
|
|||
BlockTreeDictionary* _dictionary;
|
||||
static Metablock* initialize_free_chunk(MetaWord* p, size_t word_size);
|
||||
|
||||
// Only allocate and split from freelist if the size of the allocation
|
||||
// is at least 1/4th the size of the available block.
|
||||
const static int WasteMultiplier = 4;
|
||||
|
||||
// Accessors
|
||||
BlockTreeDictionary* dictionary() const { return _dictionary; }
|
||||
|
||||
|
@ -623,6 +627,7 @@ class SpaceManager : public CHeapObj<mtClass> {
|
|||
|
||||
// Add chunk to the list of chunks in use
|
||||
void add_chunk(Metachunk* v, bool make_current);
|
||||
void retire_current_chunk();
|
||||
|
||||
Mutex* lock() const { return _lock; }
|
||||
|
||||
|
@ -807,12 +812,25 @@ MetaWord* BlockFreelist::get_block(size_t word_size) {
|
|||
}
|
||||
|
||||
Metablock* free_block =
|
||||
dictionary()->get_chunk(word_size, FreeBlockDictionary<Metablock>::exactly);
|
||||
dictionary()->get_chunk(word_size, FreeBlockDictionary<Metablock>::atLeast);
|
||||
if (free_block == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (MetaWord*) free_block;
|
||||
const size_t block_size = free_block->size();
|
||||
if (block_size > WasteMultiplier * word_size) {
|
||||
return_block((MetaWord*)free_block, block_size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MetaWord* new_block = (MetaWord*)free_block;
|
||||
assert(block_size >= word_size, "Incorrect size of block from freelist");
|
||||
const size_t unused = block_size - word_size;
|
||||
if (unused >= TreeChunk<Metablock, FreeList>::min_size()) {
|
||||
return_block(new_block + word_size, unused);
|
||||
}
|
||||
|
||||
return new_block;
|
||||
}
|
||||
|
||||
void BlockFreelist::print_on(outputStream* st) const {
|
||||
|
@ -2278,6 +2296,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) {
|
|||
ChunkIndex index = ChunkManager::list_index(new_chunk->word_size());
|
||||
|
||||
if (index != HumongousIndex) {
|
||||
retire_current_chunk();
|
||||
set_current_chunk(new_chunk);
|
||||
new_chunk->set_next(chunks_in_use(index));
|
||||
set_chunks_in_use(index, new_chunk);
|
||||
|
@ -2313,6 +2332,16 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) {
|
|||
}
|
||||
}
|
||||
|
||||
void SpaceManager::retire_current_chunk() {
|
||||
if (current_chunk() != NULL) {
|
||||
size_t remaining_words = current_chunk()->free_word_size();
|
||||
if (remaining_words >= TreeChunk<Metablock, FreeList>::min_size()) {
|
||||
block_freelists()->return_block(current_chunk()->allocate(remaining_words), remaining_words);
|
||||
inc_used_metrics(remaining_words);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Metachunk* SpaceManager::get_new_chunk(size_t word_size,
|
||||
size_t grow_chunks_by_words) {
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue