--- old/src/hotspot/share/gc/z/zHeap.cpp 2019-07-26 14:17:43.948820090 +0200 +++ new/src/hotspot/share/gc/z/zHeap.cpp 2019-07-26 14:17:43.678811210 +0200 @@ -25,6 +25,7 @@ #include "gc/shared/gcArguments.hpp" #include "gc/shared/oopStorage.hpp" #include "gc/z/zAddress.hpp" +#include "gc/z/zArray.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zHeap.inline.hpp" #include "gc/z/zHeapIterator.hpp" @@ -386,6 +387,22 @@ _reference_processor.enqueue_references(); } +class ZHeapReclaimPagesTask : public ZTask { +private: + ZArrayParallelIterator _iter; + +public: + ZHeapReclaimPagesTask(ZArray* pages) : + ZTask("ZHeapReclaimPagesTask"), + _iter(pages) {} + + virtual void work() { + for (ZPage* page; _iter.next(&page);) { + ZHeap::heap()->free_page(page, true /* reclaimed */); + } + } +}; + void ZHeap::select_relocation_set() { // Do not allow pages to be deleted _page_allocator.enable_deferred_delete(); @@ -403,17 +420,18 @@ // Register live page selector.register_live_page(page); } else { - // Register garbage page - selector.register_garbage_page(page); - - // Reclaim page immediately - free_page(page, true /* reclaimed */); + // Register reclaimable page + selector.register_reclaimable_page(page); } } // Allow pages to be deleted _page_allocator.disable_deferred_delete(); + // Free reclaimable page + ZHeapReclaimPagesTask task(selector.reclaimable()); + _workers.run_concurrent(&task); + // Select pages to relocate selector.select(&_relocation_set); --- old/src/hotspot/share/gc/z/zRelocationSetSelector.cpp 2019-07-26 14:17:44.358833575 +0200 +++ new/src/hotspot/share/gc/z/zRelocationSetSelector.cpp 2019-07-26 14:17:44.065823938 +0200 @@ -169,6 +169,7 @@ ZRelocationSetSelector::ZRelocationSetSelector() : _small("Small", ZPageSizeSmall, ZObjectSizeLimitSmall), _medium("Medium", ZPageSizeMedium, ZObjectSizeLimitMedium), + _reclaimable(), _live(0), _garbage(0), _fragmentation(0) {} @@ -190,10 +191,15 @@ _garbage += garbage; } -void ZRelocationSetSelector::register_garbage_page(ZPage* page) { +void ZRelocationSetSelector::register_reclaimable_page(ZPage* page) { + _reclaimable.add(page); _garbage += page->size(); } +ZArray* ZRelocationSetSelector::reclaimable() { + return &_reclaimable; +} + void ZRelocationSetSelector::select(ZRelocationSet* relocation_set) { // Select pages to relocate. The resulting relocation set will be // sorted such that medium pages comes first, followed by small --- old/src/hotspot/share/gc/z/zRelocationSetSelector.hpp 2019-07-26 14:17:44.705844988 +0200 +++ new/src/hotspot/share/gc/z/zRelocationSetSelector.hpp 2019-07-26 14:17:44.471837292 +0200 @@ -64,6 +64,7 @@ private: ZRelocationSetSelectorGroup _small; ZRelocationSetSelectorGroup _medium; + ZArray _reclaimable; size_t _live; size_t _garbage; size_t _fragmentation; @@ -72,7 +73,9 @@ ZRelocationSetSelector(); void register_live_page(ZPage* page); - void register_garbage_page(ZPage* page); + void register_reclaimable_page(ZPage* page); + + ZArray* reclaimable(); void select(ZRelocationSet* relocation_set); size_t live() const;