8202842: G1 footprint regressions in jdk11+10

Lazily initialize G1FromCardCache to save on startup footprint if AlwaysPretouch is disabled.

Reviewed-by: sjohanss, redestad
This commit is contained in:
Thomas Schatzl 2018-05-28 11:13:21 +02:00
parent d830d47d91
commit fd0d572bb5
6 changed files with 18 additions and 12 deletions

View File

@ -1611,6 +1611,9 @@ jint G1CollectedHeap::initialize() {
const uint max_region_idx = (1U << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1;
guarantee((max_regions() - 1) <= max_region_idx, "too many regions");
// The G1FromCardCache reserves card with value 0 as "invalid", so the heap must not
// start within the first card.
guarantee(g1_rs.base() >= (char*)G1CardTable::card_size, "Java heap must not start within the first card.");
// Also create a G1 rem set.
_g1_rem_set = new G1RemSet(this, _card_table, _hot_card_cache);
_g1_rem_set->initialize(max_capacity(), max_regions());

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -47,7 +47,9 @@ void G1FromCardCache::initialize(uint num_par_rem_sets, uint max_num_regions) {
num_par_rem_sets,
&_static_mem_size);
invalidate(0, _max_regions);
if (AlwaysPreTouch) {
invalidate(0, _max_regions);
}
}
void G1FromCardCache::invalidate(uint start_idx, size_t new_num_regions) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,7 +31,7 @@
// G1FromCardCache remembers the most recently processed card on the heap on
// a per-region and per-thread basis.
class G1FromCardCache : public AllStatic {
private:
private:
// Array of card indices. Indexed by heap region (rows) and thread (columns) to minimize
// thread contention.
// This order minimizes the time to clear all entries for a given region during region
@ -49,9 +49,12 @@ class G1FromCardCache : public AllStatic {
}
#endif
public:
static const uintptr_t InvalidCard = UINTPTR_MAX;
// This card index indicates "no card for that entry" yet. This allows us to use the OS
// lazy backing of memory with zero-filled pages to avoid initial actual memory use.
// This means that the heap must not contain card zero.
static const uintptr_t InvalidCard = 0;
public:
static void clear(uint region_idx);
// Returns true if the given card is in the cache at the given location, or

View File

@ -36,9 +36,6 @@ G1RegionMarkStatsCache::G1RegionMarkStatsCache(G1RegionMarkStats* target, uint m
guarantee(is_power_of_2(num_cache_entries),
"Number of cache entries must be power of two, but is %u", num_cache_entries);
_cache = NEW_C_HEAP_ARRAY(G1RegionMarkStatsCacheEntry, _num_cache_entries, mtGC);
for (uint i = 0; i < _num_cache_entries; i++) {
_cache[i].clear();
}
_num_cache_entries_mask = _num_cache_entries - 1;
}

View File

@ -104,6 +104,8 @@ class Padded2DArray {
public:
// Creates an aligned padded 2D array.
// The memory cannot be deleted since the raw memory chunk is not returned.
// Always uses mmap to reserve memory. Only the first few pages with the index to
// the rows are touched. Allocation size should be "large" to cover page overhead.
static T** create_unfreeable(uint rows, uint columns, size_t* allocation_size = NULL);
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,9 +62,8 @@ T** Padded2DArray<T, flags, alignment>::create_unfreeable(uint rows, uint column
size_t total_size = table_size + rows * row_size + alignment;
// Allocate a chunk of memory large enough to allow alignment of the chunk.
void* chunk = AllocateHeap(total_size, flags);
void* chunk = MmapArrayAllocator<uint8_t>::allocate(total_size, flags);
// Clear the allocated memory.
memset(chunk, 0, total_size);
// Align the chunk of memory.
T** result = (T**)align_up(chunk, alignment);
void* data_start = (void*)((uintptr_t)result + table_size);