1 Star 0 Fork 81

justinwm/openjdk-1.8.0

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
G1Ucommit-Refactor-Trigger-mechanism.patch 24.31 KB
一键复制 编辑 原始数据 按行查看 历史
kuen 提交于 2021-12-10 12:19 . I4LXX3: G1Ucommit Refactor Trigger mechanism
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
From f6f0d05f65a35672f48f63d7e8f73a8c2f56d1c3 Mon Sep 17 00:00:00 2001
From: mashoubing <mashoubing1@huawei.com>
Date: Wed, 25 Aug 2021 14:22:13 +0800
Subject: [PATCH 4/4] G1Ucommit: Refactor Trigger mechanism
---
.../g1/concurrentG1RefineThread.cpp | 65 ---------------
.../g1/concurrentG1RefineThread.hpp | 1 -
.../gc_implementation/g1/concurrentMark.cpp | 2 +-
.../gc_implementation/g1/g1CollectedHeap.cpp | 51 ++++++++----
.../gc_implementation/g1/g1CollectedHeap.hpp | 5 +-
.../g1/g1CollectorPolicy.cpp | 60 --------------
.../g1/g1CollectorPolicy.hpp | 20 +----
.../gc_implementation/g1/g1UncommitThread.cpp | 82 ++++++++++++++++++-
.../gc_implementation/g1/g1UncommitThread.hpp | 2 +
.../g1/heapRegionManager.cpp | 28 ++++---
.../g1/heapRegionManager.hpp | 2 +-
.../g1/heapRegionManager.inline.hpp | 2 +-
12 files changed, 142 insertions(+), 178 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp
index 98a43ba62..e4ec84895 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp
@@ -100,69 +100,6 @@ void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
}
}
-bool ConcurrentG1RefineThread::should_start_periodic_gc() {
- // If we are currently in a concurrent mark we are going to uncommit memory soon.
- if (G1CollectedHeap::heap()->concurrent_mark()->cmThread()->during_cycle()) {
- if (G1UncommitLog) {
- gclog_or_tty->print_cr("Concurrent cycle in progress. Skipping.");
- }
- return false;
- }
-
- // Check if enough time has passed since the last GC.
- uintx time_since_last_gc;
- if ((time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc()) < G1PeriodicGCInterval) {
- if (G1UncommitLog) {
- gclog_or_tty->print_cr("Last GC occurred " UINTX_FORMAT "ms before which is below threshold " UINTX_FORMAT "ms. Skipping.",
- time_since_last_gc, G1PeriodicGCInterval);
- }
- return false;
- }
-
- return true;
-}
-
-void ConcurrentG1RefineThread::check_for_periodic_gc() {
- if (!G1Uncommit) {
- return;
- }
-
- assert(G1PeriodicGCInterval > 0, "just checking");
- double recent_load = -1.0;
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- G1CollectorPolicy* g1p = g1h->g1_policy();
- if (G1PeriodicGCLoadThreshold) {
- // Sample process load and store it
- if (G1PeriodicGCProcessLoad) {
- recent_load = os::get_process_load() * 100;
- }
- if (recent_load < 0) {
- // Fallback to os load
- G1PeriodicGCProcessLoad = false;
- if (os::loadavg(&recent_load, 1) != -1) {
- static int cpu_count = os::active_processor_count();
- assert(cpu_count > 0, "just checking");
- recent_load = recent_load * 100 / cpu_count;
- }
- }
- if (recent_load >= 0) {
- g1p->add_os_load(recent_load);
- }
- }
-
- double now = os::elapsedTime();
- if (now - _last_periodic_gc_attempt_s > G1PeriodicGCInterval / 1000.0) {
- if (G1UncommitLog) {
- recent_load < 0 ? gclog_or_tty->print_cr("Checking for periodic GC.")
- : gclog_or_tty->print_cr("Checking for periodic GC. Current load %1.2f. Heap total " UINT32_FORMAT " free " UINT32_FORMAT, recent_load, g1h->_hrm.length(), g1h->_hrm.num_free_regions());
- }
- if (should_start_periodic_gc()) {
- g1p->set_periodic_gc();
- }
- _last_periodic_gc_attempt_s = now;
- }
-}
-
void ConcurrentG1RefineThread::run_young_rs_sampling() {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
_vtime_start = os::elapsedVTime();
@@ -175,8 +112,6 @@ void ConcurrentG1RefineThread::run_young_rs_sampling() {
_vtime_accum = 0.0;
}
- check_for_periodic_gc();
-
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
if (_should_terminate) {
break;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp
index 8fa521371..6c712fd2d 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp
@@ -71,7 +71,6 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
void deactivate();
void check_for_periodic_gc();
- bool should_start_periodic_gc();
public:
virtual void run();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
index 447bee183..831ec94fa 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
@@ -1354,7 +1354,7 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
satb_mq_set.set_active_all_threads(false, /* new active value */
true /* expected_active */);
- g1h->extract_uncommit_list();
+ g1h->shrink_heap_at_remark();
if (VerifyDuringGC) {
HandleMark hm; // handle scope
Universe::heap()->prepare_for_verify();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index 1f1042caa..6ee33fd05 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -1565,6 +1565,19 @@ void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) {
void
G1CollectedHeap::
resize_if_necessary_after_full_collection(size_t word_size) {
+ bool should_expand;
+ size_t resize_amount = full_collection_resize_amount(should_expand);
+
+ if (resize_amount == 0) {
+ return;
+ } else if (should_expand) {
+ expand(resize_amount);
+ } else {
+ shrink(resize_amount);
+ }
+}
+
+size_t G1CollectedHeap::full_collection_resize_amount(bool& expand) {
// Include the current allocation, if any, and bytes that will be
// pre-allocated to support collections, as "used".
const size_t capacity_after_gc = capacity();
@@ -1630,8 +1643,8 @@ resize_if_necessary_after_full_collection(size_t word_size) {
ergo_format_byte_perc("min desired capacity"),
capacity_after_gc, used_after_gc,
minimum_desired_capacity, (double) MinHeapFreeRatio);
- expand(expand_bytes);
-
+ expand = true;
+ return expand_bytes;
// No expansion, now see if we want to shrink
} else if (capacity_after_gc > maximum_desired_capacity) {
// Capacity too large, compute shrinking size
@@ -1645,10 +1658,13 @@ resize_if_necessary_after_full_collection(size_t word_size) {
ergo_format_byte_perc("max desired capacity"),
capacity_after_gc, used_after_gc,
maximum_desired_capacity, (double) MaxHeapFreeRatio);
- shrink(shrink_bytes);
+ expand = false;
+ return shrink_bytes;
}
-}
+ expand = true;
+ return 0;
+}
HeapWord*
G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
@@ -2185,12 +2201,6 @@ void G1CollectedHeap::stop() {
}
}
-void G1CollectedHeap::check_trigger_periodic_gc() {
- if (g1_policy()->should_trigger_periodic_gc()) {
- collect(GCCause::_g1_periodic_collection);
- }
-}
-
void G1CollectedHeap::init_periodic_gc_thread() {
if (_uncommit_thread == NULL && G1Uncommit) {
PeriodicGC::start();
@@ -2198,10 +2208,22 @@ void G1CollectedHeap::init_periodic_gc_thread() {
}
}
-void G1CollectedHeap::extract_uncommit_list() {
- if (g1_policy()->can_extract_uncommit_list()) {
- uint count = _hrm.extract_uncommit_list();
- g1_policy()->record_extract_uncommit_list(count);
+void G1CollectedHeap::shrink_heap_at_remark() {
+ if (!G1Uncommit) {
+ return;
+ }
+
+ bool should_expand;
+ size_t resize_amount = full_collection_resize_amount(should_expand);
+ uint length = _hrm.length();
+
+ if (resize_amount > 0 && !should_expand) {
+ uint num_candidate_to_remove = (uint)(resize_amount / HeapRegion::GrainBytes);
+ uint count = _hrm.extract_uncommit_list(num_candidate_to_remove);
+
+ gclog_or_tty->print(" [G1Uncommit list " UINT32_FORMAT ", remaining " UINT32_FORMAT
+ ", free list " UINT32_FORMAT "]",
+ count, length - count, _hrm.num_free_regions());
}
}
@@ -4037,7 +4059,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
double pause_start_sec = os::elapsedTime();
- g1_policy()->record_gc_start(pause_start_sec);
g1_policy()->phase_times()->note_gc_start(active_workers, mark_in_progress());
log_gc_header();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
index 3225967b3..d0ec5a773 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
@@ -626,6 +626,8 @@ protected:
// and will be considered part of the used portion of the heap.
void resize_if_necessary_after_full_collection(size_t word_size);
+ size_t full_collection_resize_amount(bool& expand);
+
// Callback from VM_G1CollectForAllocation operation.
// This function does everything necessary/possible to satisfy a
// failed allocation request (including collection, expansion, etc.)
@@ -1026,9 +1028,8 @@ public:
void set_refine_cte_cl_concurrency(bool concurrent);
- void check_trigger_periodic_gc();
void init_periodic_gc_thread();
- void extract_uncommit_list();
+ void shrink_heap_at_remark();
RefToScanQueue *task_queue(int i) const;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
index 099762f2b..05ce59987 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
@@ -89,7 +89,6 @@ G1CollectorPolicy::G1CollectorPolicy() :
_concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
_alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
- _heap_size_seq(new TruncatedSeq(TruncatedSeqLength)),
_os_load_seq(new TruncatedSeq(TruncatedSeqLength)),
_gc_count_seq(new TruncatedSeq(TruncatedSeqLength)),
_prev_collection_pause_end_ms(0.0),
@@ -112,11 +111,9 @@ G1CollectorPolicy::G1CollectorPolicy() :
_pause_time_target_ms((double) MaxGCPauseMillis),
_gcs_are_young(true),
- _periodic_gc(false),
_last_uncommit_attempt_s(0.0),
_os_load(-1.0),
_uncommit_start_time(0),
- _gc_count_cancel_extract(false),
_gc_count(0),
_gc_count_minute(0),
@@ -160,7 +157,6 @@ G1CollectorPolicy::G1CollectorPolicy() :
_inc_cset_predicted_elapsed_time_ms(0.0),
_inc_cset_predicted_elapsed_time_ms_diffs(0.0),
_collection_pause_end_millis(os::javaTimeNanos() / NANOSECS_PER_MILLISEC),
- _extract_uncommit_list(0),
#ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
#endif // _MSC_VER
@@ -1211,8 +1207,6 @@ void G1CollectorPolicy::record_heap_size_info_at_start(bool full) {
_heap_capacity_bytes_before_gc = _g1->capacity();
_heap_used_bytes_before_gc = _g1->used();
_cur_collection_pause_used_regions_at_start = _g1->num_used_regions();
- _heap_size_seq->add(_cur_collection_pause_used_regions_at_start);
-
_eden_capacity_bytes_before_gc =
(_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc;
@@ -1255,13 +1249,6 @@ void G1CollectorPolicy::print_detailed_heap_transition(bool full) {
EXT_SIZE_PARAMS(heap_used_bytes_after_gc),
EXT_SIZE_PARAMS(heap_capacity_bytes_after_gc));
- if (_extract_uncommit_list) {
- gclog_or_tty->print(" [Uncommit list " UINT32_FORMAT ", remaining " UINT32_FORMAT ", free list " UINT32_FORMAT "]",
- _extract_uncommit_list,
- _g1->_hrm.length(),
- _g1->_hrm.num_free_regions());
- _extract_uncommit_list = 0;
- }
if (full) {
MetaspaceAux::print_metaspace_change(_metaspace_used_bytes_before_gc);
}
@@ -2175,53 +2162,6 @@ void G1CollectorPolicy::finalize_cset(double target_pause_time_ms, EvacuationInf
evacuation_info.set_collectionset_regions(cset_region_length());
}
-void G1CollectorPolicy::record_gc_start(double curr_sec) {
- if (_uncommit_start_time == 0) {
- _uncommit_start_time = curr_sec + G1UncommitDelay;
- }
- long curr = curr_sec / 60;
- if (curr > _gc_count_minute) {
- int diff = curr - _gc_count_minute;
- _gc_count_seq->add(_gc_count);
- for (int i = 1; i < diff; i++) {
- _gc_count_seq->add(0.0);
- }
- _gc_count_minute = curr;
- double gc_count_expected = get_new_prediction(_gc_count_seq);
- // Considering the test result, 15000 is an appropriate value for G1PeriodicGCInterval.
- _gc_count_cancel_extract = gc_count_expected > MIN2(4.0, 60000.0 / G1PeriodicGCInterval);
- _gc_count = 0;
- }
- _gc_count++;
-}
-
-bool G1CollectorPolicy::should_trigger_periodic_gc() {
- if (G1PeriodicGCLoadThreshold && _os_load > G1PeriodicGCLoadThreshold) {
- _periodic_gc = false;
- } else if (_periodic_gc) {
- _periodic_gc = false;
- return true;
- }
- return false;
-}
-
-bool G1CollectorPolicy::can_extract_uncommit_list() {
- double now = os::elapsedTime();
- if (G1Uncommit && now > _uncommit_start_time) {
- if (G1PeriodicGCLoadThreshold && _os_load > G1PeriodicGCLoadThreshold) {
- return false;
- }
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- if (!_gc_count_cancel_extract || now >= (g1h->millis_since_last_gc() + G1PeriodicGCInterval) / 1000.0) {
- if (now - _last_uncommit_attempt_s >= G1PeriodicGCInterval / 1000.0) {
- _last_uncommit_attempt_s = now;
- return true;
- }
- }
- }
- return false;
-}
-
void TraceGen0TimeData::record_start_collection(double time_to_stop_the_world_ms) {
if(TraceGen0Time) {
_all_stop_world_times_ms.add(time_to_stop_the_world_ms);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
index 1a0d20d6f..af5d5d57a 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
@@ -244,7 +244,6 @@ private:
TruncatedSeq* _constant_other_time_ms_seq;
TruncatedSeq* _young_other_cost_per_region_ms_seq;
TruncatedSeq* _non_young_other_cost_per_region_ms_seq;
- TruncatedSeq* _heap_size_seq;
TruncatedSeq* _os_load_seq;
TruncatedSeq* _gc_count_seq;
@@ -268,8 +267,6 @@ private:
uint _free_regions_at_end_of_collection;
- uint _extract_uncommit_list;
-
size_t _recorded_rs_lengths;
size_t _max_rs_lengths;
double _sigma;
@@ -308,19 +305,12 @@ private:
size_t _gc_count;
long _gc_count_minute;
- bool _gc_count_cancel_extract;
- volatile bool _periodic_gc;
double _last_uncommit_attempt_s;
volatile double _os_load;
double _uncommit_start_time;
public:
// Accessors
-
- void set_periodic_gc() { _periodic_gc = true; }
- bool can_extract_uncommit_list();
- bool should_trigger_periodic_gc();
-
void set_region_eden(HeapRegion* hr, int young_index_in_cset) {
hr->set_eden();
hr->install_surv_rate_group(_short_lived_surv_rate_group);
@@ -346,16 +336,14 @@ public:
_max_rs_lengths = rs_lengths;
}
- size_t predict_heap_size_seq() {
- return (size_t) get_new_prediction(_heap_size_seq);
- }
-
void add_os_load(double load) {
_os_load_seq->add(load);
_os_load = get_new_prediction(_os_load_seq);
}
- void record_gc_start(double sec);
+ double os_load() {
+ return _os_load;
+ }
size_t predict_rs_length_diff() {
return (size_t) get_new_prediction(_rs_length_diff_seq);
@@ -739,8 +727,6 @@ public:
void record_stop_world_start();
void record_concurrent_pause();
- void record_extract_uncommit_list(uint count) { _extract_uncommit_list = count; }
-
// Record how much space we copied during a GC. This is typically
// called when a GC alloc region is being retired.
void record_bytes_copied_during_gc(size_t bytes) {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp
index 37bdbdb69..503218917 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.cpp
@@ -26,6 +26,9 @@
#include "gc_implementation/g1/g1UncommitThread.hpp"
#include "gc_implementation/g1/g1_globals.hpp"
+#include "gc_implementation/g1/g1Log.hpp"
+#include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/concurrentMarkThread.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/os.hpp"
@@ -104,9 +107,12 @@ void PeriodicGC::start() {
}
void PeriodicGC::timer_thread_entry(JavaThread* thread, TRAPS) {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
while(!_should_terminate) {
assert(!SafepointSynchronize::is_at_safepoint(), "PeriodicGC timer thread is a JavaThread");
- G1CollectedHeap::heap()->check_trigger_periodic_gc();
+ if (check_for_periodic_gc()) {
+ g1h->collect(GCCause::_g1_periodic_collection);
+ }
MutexLockerEx x(_monitor);
if (_should_terminate) {
@@ -116,6 +122,78 @@ void PeriodicGC::timer_thread_entry(JavaThread* thread, TRAPS) {
}
}
+bool PeriodicGC::check_for_periodic_gc() {
+ if (!G1Uncommit) {
+ return false;
+ }
+
+ return should_start_periodic_gc();
+}
+
+bool PeriodicGC::should_start_periodic_gc() {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ G1CollectorPolicy* g1p = g1h->g1_policy();
+ // If we are currently in a concurrent mark we are going to uncommit memory soon.
+ if (g1h->concurrent_mark()->cmThread()->during_cycle()) {
+ if (G1UncommitLog && G1Log::finest()) {
+ gclog_or_tty->date_stamp(PrintGCDateStamps);
+ gclog_or_tty->stamp(PrintGCTimeStamps);
+ gclog_or_tty->print_cr("[G1Uncommit] Concurrent cycle in progress. Skipping.");
+ }
+ return false;
+ }
+
+ // Check if enough time has passed since the last GC.
+ uintx time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc();
+ if (time_since_last_gc < G1PeriodicGCInterval) {
+ if (G1UncommitLog && G1Log::finest()) {
+ gclog_or_tty->date_stamp(PrintGCDateStamps);
+ gclog_or_tty->stamp(PrintGCTimeStamps);
+ gclog_or_tty->print_cr("[G1Uncommit] Last GC occurred " UINTX_FORMAT "ms before which is below threshold"
+ UINTX_FORMAT "ms. Skipping.", time_since_last_gc, G1PeriodicGCInterval);
+ }
+ return false;
+ }
+
+ // Collect load need G1PeriodicGCInterval time after previous GC's end
+ assert(G1PeriodicGCInterval > 0, "just checking");
+ double recent_load = -1.0;
+
+ if (G1PeriodicGCLoadThreshold) {
+ // Sample process load and store it
+ if (G1PeriodicGCProcessLoad) {
+ recent_load = os::get_process_load() * 100;
+ }
+ if (recent_load < 0) {
+ // Fallback to os load
+ G1PeriodicGCProcessLoad = false;
+ if (os::loadavg(&recent_load, 1) != -1) {
+ static int cpu_count = os::active_processor_count();
+ assert(cpu_count > 0, "just checking");
+ recent_load = recent_load * 100 / cpu_count;
+ }
+ }
+ if (recent_load >= 0) {
+ g1p->add_os_load(recent_load);
+ }
+ }
+
+ if (G1UncommitLog) {
+ gclog_or_tty->date_stamp(PrintGCDateStamps);
+ gclog_or_tty->stamp(PrintGCTimeStamps);
+ recent_load < 0 ? gclog_or_tty->print_cr("[G1Uncommit] Checking for periodic GC.")
+ : gclog_or_tty->print_cr("[G1Uncommit] Checking for periodic GC. Current load %1.2f. "
+ "total regions: " UINT32_FORMAT" free regions: " UINT32_FORMAT,
+ recent_load, g1h->num_regions(), g1h->num_free_regions());
+ }
+
+ if (g1p->os_load() < G1PeriodicGCLoadThreshold || !G1PeriodicGCLoadThreshold) {
+ return true;
+ }
+ gclog_or_tty->print_cr("[G1Uncommit] Periodic GC request denied, skipping!");
+ return false;
+}
+
void PeriodicGC::stop() {
_should_terminate = true;
{
@@ -139,7 +217,7 @@ G1UncommitThread::G1UncommitThread() :
}
}
if (G1UncommitLog) {
- gclog_or_tty->print_cr("Periodic GC Thread start");
+ gclog_or_tty->print_cr("[G1Uncommit] Periodic GC Thread start");
}
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.hpp
index 883a9a418..6f1d5e35f 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1UncommitThread.hpp
@@ -40,6 +40,8 @@ public:
static void start();
static void stop();
static bool has_error(TRAPS, const char* error);
+ static bool check_for_periodic_gc();
+ static bool should_start_periodic_gc();
};
class G1UncommitThread: public ConcurrentGCThread {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp
index 56e2d32df..d31073f9f 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp
@@ -573,21 +573,23 @@ void HeapRegionManager::free_uncommit_list_memory() {
}
}
-uint HeapRegionManager::extract_uncommit_list()
-{
+uint HeapRegionManager::extract_uncommit_list(uint num_candidate_to_remove) {
assert_at_safepoint(true /* should_be_vm_thread */);
+ double start_up_sec = os::elapsedTime();
+ if (start_up_sec < G1UncommitDelay) {
+ gclog_or_tty->date_stamp(PrintGCDateStamps);
+ gclog_or_tty->stamp(PrintGCTimeStamps);
+ gclog_or_tty->print_cr("start up seconds:%lf, less than G1UncommitDelay, will not uncommit.", start_up_sec);
+ return 0;
+ }
+
if (!_uncommit_list_filled) {
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- uint dest = ((G1CollectorPolicy*)g1h->collector_policy())->predict_heap_size_seq();
-
- if (dest < _num_committed) {
- uint num_regions_to_remove = (_num_committed - dest) * G1UncommitPercent;
- if (num_regions_to_remove >= 1 && num_regions_to_remove < _free_list.length()) {
- int count = _free_list.move_regions_to(&_uncommit_list, num_regions_to_remove);
- OrderAccess::storestore();
- _uncommit_list_filled = true;
- return count;
- }
+ uint num_regions_to_remove = num_candidate_to_remove * G1UncommitPercent;
+ if (num_regions_to_remove >= 1 && num_regions_to_remove < _free_list.length()) {
+ int count = _free_list.move_regions_to(&_uncommit_list, num_regions_to_remove);
+ OrderAccess::storestore();
+ _uncommit_list_filled = true;
+ return count;
}
}
return 0;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp
index 25f3a223f..3950d6280 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp
@@ -175,7 +175,7 @@ public:
G1RegionToSpaceMapper* cardtable,
G1RegionToSpaceMapper* card_counts);
- uint extract_uncommit_list();
+ uint extract_uncommit_list(uint num_candidate_to_remove);
void free_uncommit_list_memory();
// Return the "dummy" region used for G1AllocRegion. This is currently a hardwired
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp
index 68840d61e..50d0fa832 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp
@@ -40,8 +40,8 @@ inline HeapRegion* HeapRegionManager::addr_to_region(HeapWord* addr) const {
}
inline HeapRegion* HeapRegionManager::at(uint index) const {
- assert(is_available(index), "pre-condition");
HeapRegion* hr = _regions.get_by_index(index);
+ assert(hr->in_uncommit_list() || is_available(index), "pre-condition");
assert(hr != NULL, "sanity");
assert(hr->hrm_index() == index, "sanity");
return hr;
--
2.22.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/justinwm/openjdk-1.8.0.git
git@gitee.com:justinwm/openjdk-1.8.0.git
justinwm
openjdk-1.8.0
openjdk-1.8.0
master

搜索帮助