提交 708c714d 编写于 作者: J jmasa

7189971: Implement CMSWaitDuration for non-incremental mode of CMS

Reviewed-by: jmasa, johnc, ysr
Contributed-by: michal@frajt.eu
上级 a975965f
......@@ -300,8 +300,7 @@ void ConcurrentMarkSweepThread::desynchronize(bool is_cms_thread) {
}
}
// Wait until the next synchronous GC, a concurrent full gc request,
// or a timeout, whichever is earlier.
// Wait until any cms_lock event
void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) {
MutexLockerEx x(CGC_lock,
Mutex::_no_safepoint_check_flag);
......@@ -315,15 +314,100 @@ void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) {
"Should not be set");
}
// Wait until the next synchronous GC, a concurrent full gc request,
// or a timeout, whichever is earlier.
void ConcurrentMarkSweepThread::wait_on_cms_lock_for_scavenge(long t_millis) {
// Wait time in millis or 0 value representing infinite wait for a scavenge
assert(t_millis >= 0, "Wait time for scavenge should be 0 or positive");
GenCollectedHeap* gch = GenCollectedHeap::heap();
double start_time_secs = os::elapsedTime();
double end_time_secs = start_time_secs + (t_millis / ((double) MILLIUNITS));
// Total collections count before waiting loop
unsigned int before_count;
{
MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
before_count = gch->total_collections();
}
unsigned int loop_count = 0;
while(!_should_terminate) {
double now_time = os::elapsedTime();
long wait_time_millis;
if(t_millis != 0) {
// New wait limit
wait_time_millis = (long) ((end_time_secs - now_time) * MILLIUNITS);
if(wait_time_millis <= 0) {
// Wait time is over
break;
}
} else {
// No wait limit, wait if necessary forever
wait_time_millis = 0;
}
// Wait until the next event or the remaining timeout
{
MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
if (_should_terminate || _collector->_full_gc_requested) {
return;
}
set_CMS_flag(CMS_cms_wants_token); // to provoke notifies
assert(t_millis == 0 || wait_time_millis > 0, "Sanity");
CGC_lock->wait(Mutex::_no_safepoint_check_flag, wait_time_millis);
clear_CMS_flag(CMS_cms_wants_token);
assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
"Should not be set");
}
// Extra wait time check before entering the heap lock to get the collection count
if(t_millis != 0 && os::elapsedTime() >= end_time_secs) {
// Wait time is over
break;
}
// Total collections count after the event
unsigned int after_count;
{
MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
after_count = gch->total_collections();
}
if(before_count != after_count) {
// There was a collection - success
break;
}
// Too many loops warning
if(++loop_count == 0) {
warning("wait_on_cms_lock_for_scavenge() has looped %u times", loop_count - 1);
}
}
}
void ConcurrentMarkSweepThread::sleepBeforeNextCycle() {
while (!_should_terminate) {
if (CMSIncrementalMode) {
icms_wait();
if(CMSWaitDuration >= 0) {
// Wait until the next synchronous GC, a concurrent full gc
// request or a timeout, whichever is earlier.
wait_on_cms_lock_for_scavenge(CMSWaitDuration);
}
return;
} else {
if(CMSWaitDuration >= 0) {
// Wait until the next synchronous GC, a concurrent full gc
// request or a timeout, whichever is earlier.
wait_on_cms_lock(CMSWaitDuration);
wait_on_cms_lock_for_scavenge(CMSWaitDuration);
} else {
// Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently
wait_on_cms_lock(CMSCheckInterval);
}
}
// Check if we should start a CMS collection cycle
if (_collector->shouldConcurrentCollect()) {
......
......@@ -130,6 +130,12 @@ class ConcurrentMarkSweepThread: public ConcurrentGCThread {
// A concurrent full gc request terminates the wait.
void wait_on_cms_lock(long t_millis);
// Wait on CMS lock until the next synchronous GC
// or given timeout, whichever is earlier. A timeout value
// of 0 indicates that there is no upper bound on the wait time.
// A concurrent full gc request terminates the wait.
void wait_on_cms_lock_for_scavenge(long t_millis);
// The CMS thread will yield during the work portion of its cycle
// only when requested to. Both synchronous and asychronous requests
// are provided:
......
......@@ -1751,6 +1751,10 @@ class CommandLineFlags {
manageable(intx, CMSWaitDuration, 2000, \
"Time in milliseconds that CMS thread waits for young GC") \
\
develop(uintx, CMSCheckInterval, 1000, \
"Interval in milliseconds that CMS thread checks if it " \
"should start a collection cycle") \
\
product(bool, CMSYield, true, \
"Yield between steps of concurrent mark & sweep") \
\
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册