mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
6362677: Change parallel GC collector default number of parallel GC threads
Use the same default number of GC threads as used by ParNewGC and ConcMarkSweepGC (i.e., the 5/8th rule). Reviewed-by: ysr, tonyp
This commit is contained in:
parent
74f243990c
commit
63f1de52fc
8 changed files with 174 additions and 81 deletions
|
@ -924,10 +924,18 @@ static void no_shared_spaces() {
|
|||
void Arguments::set_parnew_gc_flags() {
|
||||
assert(!UseSerialGC && !UseParallelGC, "control point invariant");
|
||||
|
||||
// Turn off AdaptiveSizePolicy by default for parnew until it is
|
||||
// complete.
|
||||
if (UseParNewGC &&
|
||||
FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) {
|
||||
FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false);
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(UseParNewGC) && ParallelGCThreads > 1) {
|
||||
FLAG_SET_DEFAULT(UseParNewGC, true);
|
||||
} else if (UseParNewGC && ParallelGCThreads == 0) {
|
||||
FLAG_SET_DEFAULT(ParallelGCThreads, nof_parallel_gc_threads());
|
||||
FLAG_SET_DEFAULT(ParallelGCThreads,
|
||||
Abstract_VM_Version::parallel_worker_threads());
|
||||
if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) {
|
||||
FLAG_SET_DEFAULT(UseParNewGC, false);
|
||||
}
|
||||
|
@ -956,25 +964,6 @@ void Arguments::set_parnew_gc_flags() {
|
|||
}
|
||||
}
|
||||
|
||||
// CAUTION: this code is currently shared by UseParallelGC, UseParNewGC and
|
||||
// UseconcMarkSweepGC. Further tuning of individual collectors might
|
||||
// dictate refinement on a per-collector basis.
|
||||
int Arguments::nof_parallel_gc_threads() {
|
||||
if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
|
||||
// For very large machines, there are diminishing returns
|
||||
// for large numbers of worker threads. Instead of
|
||||
// hogging the whole system, use 5/8ths of a worker for every
|
||||
// processor after the first 8. For example, on a 72 cpu
|
||||
// machine use 8 + (72 - 8) * (5/8) == 48 worker threads.
|
||||
// This is just a start and needs further tuning and study in
|
||||
// Tiger.
|
||||
int ncpus = os::active_processor_count();
|
||||
return (ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8);
|
||||
} else {
|
||||
return ParallelGCThreads;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust some sizes to suit CMS and/or ParNew needs; these work well on
|
||||
// sparc/solaris for certain applications, but would gain from
|
||||
// further optimization and tuning efforts, and would almost
|
||||
|
@ -984,26 +973,24 @@ void Arguments::set_cms_and_parnew_gc_flags() {
|
|||
return;
|
||||
}
|
||||
|
||||
assert(UseConcMarkSweepGC, "CMS is expected to be on here");
|
||||
|
||||
// If we are using CMS, we prefer to UseParNewGC,
|
||||
// unless explicitly forbidden.
|
||||
if (UseConcMarkSweepGC && !UseParNewGC && FLAG_IS_DEFAULT(UseParNewGC)) {
|
||||
FLAG_SET_DEFAULT(UseParNewGC, true);
|
||||
if (!UseParNewGC && FLAG_IS_DEFAULT(UseParNewGC)) {
|
||||
FLAG_SET_ERGO(bool, UseParNewGC, true);
|
||||
}
|
||||
|
||||
// Turn off AdaptiveSizePolicy by default for cms until it is
|
||||
// complete. Also turn it off in general if the
|
||||
// parnew collector has been selected.
|
||||
if ((UseConcMarkSweepGC || UseParNewGC) &&
|
||||
FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) {
|
||||
// complete.
|
||||
if (FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) {
|
||||
FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false);
|
||||
}
|
||||
|
||||
// In either case, adjust ParallelGCThreads and/or UseParNewGC
|
||||
// as needed.
|
||||
set_parnew_gc_flags();
|
||||
|
||||
if (!UseConcMarkSweepGC) {
|
||||
return;
|
||||
if (UseParNewGC) {
|
||||
set_parnew_gc_flags();
|
||||
}
|
||||
|
||||
// Now make adjustments for CMS
|
||||
|
@ -1147,17 +1134,11 @@ void Arguments::set_ergonomics_flags() {
|
|||
FLAG_IS_DEFAULT(UseParallelGC)) {
|
||||
if (should_auto_select_low_pause_collector()) {
|
||||
FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true);
|
||||
set_cms_and_parnew_gc_flags();
|
||||
} else {
|
||||
FLAG_SET_ERGO(bool, UseParallelGC, true);
|
||||
}
|
||||
no_shared_spaces();
|
||||
}
|
||||
|
||||
// This is here because the parallel collector could
|
||||
// have been selected so this initialization should
|
||||
// still be done.
|
||||
set_parallel_gc_flags();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1170,6 +1151,9 @@ void Arguments::set_parallel_gc_flags() {
|
|||
// If no heap maximum was requested explicitly, use some reasonable fraction
|
||||
// of the physical memory, up to a maximum of 1GB.
|
||||
if (UseParallelGC) {
|
||||
FLAG_SET_ERGO(uintx, ParallelGCThreads,
|
||||
Abstract_VM_Version::parallel_worker_threads());
|
||||
|
||||
if (FLAG_IS_DEFAULT(MaxHeapSize)) {
|
||||
const uint64_t reasonable_fraction =
|
||||
os::physical_memory() / DefaultMaxRAMFraction;
|
||||
|
@ -1312,6 +1296,31 @@ static bool verify_serial_gc_flags() {
|
|||
UseParallelOldGC));
|
||||
}
|
||||
|
||||
// Check consistency of GC selection
|
||||
bool Arguments::check_gc_consistency() {
|
||||
bool status = true;
|
||||
// Ensure that the user has not selected conflicting sets
|
||||
// of collectors. [Note: this check is merely a user convenience;
|
||||
// collectors over-ride each other so that only a non-conflicting
|
||||
// set is selected; however what the user gets is not what they
|
||||
// may have expected from the combination they asked for. It's
|
||||
// better to reduce user confusion by not allowing them to
|
||||
// select conflicting combinations.
|
||||
uint i = 0;
|
||||
if (UseSerialGC) i++;
|
||||
if (UseConcMarkSweepGC || UseParNewGC) i++;
|
||||
if (UseParallelGC || UseParallelOldGC) i++;
|
||||
if (i > 1) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Conflicting collector combinations in option list; "
|
||||
"please refer to the release notes for the combinations "
|
||||
"allowed\n");
|
||||
status = false;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// Check the consistency of vm_init_args
|
||||
bool Arguments::check_vm_args_consistency() {
|
||||
// Method for adding checks for flag consistency.
|
||||
|
@ -1354,14 +1363,14 @@ bool Arguments::check_vm_args_consistency() {
|
|||
status = false;
|
||||
}
|
||||
|
||||
status &= verify_percentage(MaxLiveObjectEvacuationRatio,
|
||||
status = status && verify_percentage(MaxLiveObjectEvacuationRatio,
|
||||
"MaxLiveObjectEvacuationRatio");
|
||||
status &= verify_percentage(AdaptiveSizePolicyWeight,
|
||||
status = status && verify_percentage(AdaptiveSizePolicyWeight,
|
||||
"AdaptiveSizePolicyWeight");
|
||||
status &= verify_percentage(AdaptivePermSizeWeight, "AdaptivePermSizeWeight");
|
||||
status &= verify_percentage(ThresholdTolerance, "ThresholdTolerance");
|
||||
status &= verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio");
|
||||
status &= verify_percentage(MaxHeapFreeRatio, "MaxHeapFreeRatio");
|
||||
status = status && verify_percentage(AdaptivePermSizeWeight, "AdaptivePermSizeWeight");
|
||||
status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance");
|
||||
status = status && verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio");
|
||||
status = status && verify_percentage(MaxHeapFreeRatio, "MaxHeapFreeRatio");
|
||||
|
||||
if (MinHeapFreeRatio > MaxHeapFreeRatio) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
|
@ -1377,14 +1386,14 @@ bool Arguments::check_vm_args_consistency() {
|
|||
MarkSweepAlwaysCompactCount = 1; // Move objects every gc.
|
||||
}
|
||||
|
||||
status &= verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
|
||||
status &= verify_percentage(GCTimeLimit, "GCTimeLimit");
|
||||
status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
|
||||
status = status && verify_percentage(GCTimeLimit, "GCTimeLimit");
|
||||
if (GCTimeLimit == 100) {
|
||||
// Turn off gc-overhead-limit-exceeded checks
|
||||
FLAG_SET_DEFAULT(UseGCOverheadLimit, false);
|
||||
}
|
||||
|
||||
status &= verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
|
||||
status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
|
||||
|
||||
// Check user specified sharing option conflict with Parallel GC
|
||||
bool cannot_share = (UseConcMarkSweepGC || UseParallelGC ||
|
||||
|
@ -1402,24 +1411,7 @@ bool Arguments::check_vm_args_consistency() {
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure that the user has not selected conflicting sets
|
||||
// of collectors. [Note: this check is merely a user convenience;
|
||||
// collectors over-ride each other so that only a non-conflicting
|
||||
// set is selected; however what the user gets is not what they
|
||||
// may have expected from the combination they asked for. It's
|
||||
// better to reduce user confusion by not allowing them to
|
||||
// select conflicting combinations.
|
||||
uint i = 0;
|
||||
if (UseSerialGC) i++;
|
||||
if (UseConcMarkSweepGC || UseParNewGC) i++;
|
||||
if (UseParallelGC || UseParallelOldGC) i++;
|
||||
if (i > 1) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Conflicting collector combinations in option list; "
|
||||
"please refer to the release notes for the combinations "
|
||||
"allowed\n");
|
||||
status = false;
|
||||
}
|
||||
status = status && check_gc_consistency();
|
||||
|
||||
if (_has_alloc_profile) {
|
||||
if (UseParallelGC || UseParallelOldGC) {
|
||||
|
@ -1451,15 +1443,15 @@ bool Arguments::check_vm_args_consistency() {
|
|||
"allocation buffers\n(-XX:+UseTLAB).\n");
|
||||
status = false;
|
||||
} else {
|
||||
status &= verify_percentage(CMSIncrementalDutyCycle,
|
||||
status = status && verify_percentage(CMSIncrementalDutyCycle,
|
||||
"CMSIncrementalDutyCycle");
|
||||
status &= verify_percentage(CMSIncrementalDutyCycleMin,
|
||||
status = status && verify_percentage(CMSIncrementalDutyCycleMin,
|
||||
"CMSIncrementalDutyCycleMin");
|
||||
status &= verify_percentage(CMSIncrementalSafetyFactor,
|
||||
status = status && verify_percentage(CMSIncrementalSafetyFactor,
|
||||
"CMSIncrementalSafetyFactor");
|
||||
status &= verify_percentage(CMSIncrementalOffset,
|
||||
status = status && verify_percentage(CMSIncrementalOffset,
|
||||
"CMSIncrementalOffset");
|
||||
status &= verify_percentage(CMSExpAvgFactor,
|
||||
status = status && verify_percentage(CMSExpAvgFactor,
|
||||
"CMSExpAvgFactor");
|
||||
// If it was not set on the command line, set
|
||||
// CMSInitiatingOccupancyFraction to 1 so icms can initiate cycles early.
|
||||
|
@ -2064,7 +2056,8 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
|||
|
||||
// Enable parallel GC and adaptive generation sizing
|
||||
FLAG_SET_CMDLINE(bool, UseParallelGC, true);
|
||||
FLAG_SET_DEFAULT(ParallelGCThreads, nof_parallel_gc_threads());
|
||||
FLAG_SET_DEFAULT(ParallelGCThreads,
|
||||
Abstract_VM_Version::parallel_worker_threads());
|
||||
|
||||
// Encourage steady state memory management
|
||||
FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100);
|
||||
|
@ -2451,15 +2444,25 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
|||
no_shared_spaces();
|
||||
#endif // KERNEL
|
||||
|
||||
// Set some flags for ParallelGC if needed.
|
||||
set_parallel_gc_flags();
|
||||
|
||||
// Set some flags for CMS and/or ParNew collectors, as needed.
|
||||
set_cms_and_parnew_gc_flags();
|
||||
|
||||
// Set flags based on ergonomics.
|
||||
set_ergonomics_flags();
|
||||
|
||||
// Check the GC selections again.
|
||||
if (!check_gc_consistency()) {
|
||||
return JNI_EINVAL;
|
||||
}
|
||||
|
||||
if (UseParallelGC) {
|
||||
// Set some flags for ParallelGC if needed.
|
||||
set_parallel_gc_flags();
|
||||
} else if (UseConcMarkSweepGC) {
|
||||
// Set some flags for CMS
|
||||
set_cms_and_parnew_gc_flags();
|
||||
} else if (UseParNewGC) {
|
||||
// Set some flags for ParNew
|
||||
set_parnew_gc_flags();
|
||||
}
|
||||
|
||||
#ifdef SERIALGC
|
||||
assert(verify_serial_gc_flags(), "SerialGC unset");
|
||||
#endif // SERIALGC
|
||||
|
@ -2479,6 +2482,12 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
|||
CommandLineFlags::printSetFlags();
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
if (PrintFlagsFinal) {
|
||||
CommandLineFlags::printFlags();
|
||||
}
|
||||
#endif
|
||||
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue