OpenJDK / amber / amber
changeset 50865:bc1336220671
8202842: G1 footprint regressions in jdk11+10
Summary: Lazily initialize G1FromCardCache to save on startup footprint if AlwaysPretouch is disabled.
Reviewed-by: sjohanss, redestad
author | tschatzl |
---|---|
date | Mon, 28 May 2018 11:13:21 +0200 |
parents | 5aaf3a471172 |
children | 4887e76f2493 2f9811d99ba8 |
files | src/hotspot/share/gc/g1/g1CollectedHeap.cpp src/hotspot/share/gc/g1/g1FromCardCache.cpp src/hotspot/share/gc/g1/g1FromCardCache.hpp src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp src/hotspot/share/memory/padded.hpp src/hotspot/share/memory/padded.inline.hpp |
diffstat | 6 files changed, 18 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Mon May 28 09:59:11 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Mon May 28 11:13:21 2018 +0200 @@ -1611,6 +1611,9 @@ 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());
--- a/src/hotspot/share/gc/g1/g1FromCardCache.cpp Mon May 28 09:59:11 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1FromCardCache.cpp Mon May 28 11:13:21 2018 +0200 @@ -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 @@ 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) {
--- a/src/hotspot/share/gc/g1/g1FromCardCache.hpp Mon May 28 09:59:11 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1FromCardCache.hpp Mon May 28 11:13:21 2018 +0200 @@ -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 @@ } #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
--- a/src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp Mon May 28 09:59:11 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp Mon May 28 11:13:21 2018 +0200 @@ -36,9 +36,6 @@ 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; }
--- a/src/hotspot/share/memory/padded.hpp Mon May 28 09:59:11 2018 +0200 +++ b/src/hotspot/share/memory/padded.hpp Mon May 28 11:13:21 2018 +0200 @@ -104,6 +104,8 @@ 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); };
--- a/src/hotspot/share/memory/padded.inline.hpp Mon May 28 09:59:11 2018 +0200 +++ b/src/hotspot/share/memory/padded.inline.hpp Mon May 28 11:13:21 2018 +0200 @@ -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 @@ 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);