From a2abc5b824de4d2b7b4529e1c854fd514ca86c9f Mon Sep 17 00:00:00 2001 From: flofriday Date: Tue, 8 Aug 2023 19:50:32 +0200 Subject: [PATCH] LibJS: Improve garbage collection trigger condition This patch triggers the collector when allocated memory doubles instead of every 100k allocations. Which can almost half (reduce by ~48%) the time spent on collection when loading google-maps. This dynamic approach is inspired by some other GCs like Golang's and Lua's and improves performance in memory heavy applications because marking must visit old objects which will dominate the marking phase if the GC is invoked too often. This commit also improves the Octane Splay benchmark and almost doubles it :^) --- Userland/Libraries/LibJS/Heap/Heap.cpp | 10 ++++++---- Userland/Libraries/LibJS/Heap/Heap.h | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibJS/Heap/Heap.cpp b/Userland/Libraries/LibJS/Heap/Heap.cpp index edc344074d..f5404a97d5 100644 --- a/Userland/Libraries/LibJS/Heap/Heap.cpp +++ b/Userland/Libraries/LibJS/Heap/Heap.cpp @@ -79,14 +79,14 @@ ALWAYS_INLINE CellAllocator& Heap::allocator_for_size(size_t cell_size) Cell* Heap::allocate_cell(size_t size) { if (should_collect_on_every_allocation()) { + m_allocated_bytes_since_last_gc = 0; collect_garbage(); - } else if (m_allocations_since_last_gc > m_max_allocations_between_gc) { - m_allocations_since_last_gc = 0; + } else if (m_allocated_bytes_since_last_gc + size > m_gc_bytes_threshold) { + m_allocated_bytes_since_last_gc = 0; collect_garbage(); - } else { - ++m_allocations_since_last_gc; } + m_allocated_bytes_since_last_gc += size; auto& allocator = allocator_for_size(size); return allocator.allocate_cell(*this); } @@ -354,6 +354,8 @@ void Heap::sweep_dead_cells(bool print_report, Core::ElapsedTimer const& measure }); } + m_gc_bytes_threshold = live_cell_bytes > GC_MIN_BYTES_THRESHOLD ? live_cell_bytes : GC_MIN_BYTES_THRESHOLD; + if (print_report) { Duration const time_spent = measurement_timer.elapsed_time(); size_t live_block_count = 0; diff --git a/Userland/Libraries/LibJS/Heap/Heap.h b/Userland/Libraries/LibJS/Heap/Heap.h index 400d2258a8..807347b5b7 100644 --- a/Userland/Libraries/LibJS/Heap/Heap.h +++ b/Userland/Libraries/LibJS/Heap/Heap.h @@ -101,8 +101,9 @@ private: } } - size_t m_max_allocations_between_gc { 100000 }; - size_t m_allocations_since_last_gc { 0 }; + static constexpr size_t GC_MIN_BYTES_THRESHOLD { 4 * 1024 * 1024 }; + size_t m_gc_bytes_threshold { GC_MIN_BYTES_THRESHOLD }; + size_t m_allocated_bytes_since_last_gc { 0 }; bool m_should_collect_on_every_allocation { false };