提交 394e03cc 编写于 作者: Y ysr

6896099: Integrate CMS heap ergo with default heap sizing ergo

6627787: CMS: JVM refuses to start up with -Xms16m -Xmx16m
7000125: CMS: Anti-monotone young gen sizing with respect to maximum whole heap size specification
7027529: CMS: retire CMSUseOldDefaults flag
Summary: Simplify CMS heap sizing code, relying on ergonomic initial sizing consistent with other collectors for the most part, controlling only young gen sizing to rein in pause times. Make CMS young gen sizing default statically cpu-dependant. Remove inconsistencies wrt generation sizing and policy code, allowing for the fixing for 6627787 and 7000125. For 7027529, retire the flag CMSUseOldDefaults which had been introduced as a bridge from JDK 5 to JDK 6 a number of years ago.
Reviewed-by: brutisso, poonam
上级 262ae530
/* /*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -51,6 +51,7 @@ define_pd_global(intx, CodeEntryAlignment, 32); ...@@ -51,6 +51,7 @@ define_pd_global(intx, CodeEntryAlignment, 32);
define_pd_global(intx, OptoLoopAlignment, 16); // = 4*wordSize define_pd_global(intx, OptoLoopAlignment, 16); // = 4*wordSize
define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC define_pd_global(intx, InlineFrequencyCount, 50); // we can use more inlining on the SPARC
define_pd_global(intx, InlineSmallCode, 1500); define_pd_global(intx, InlineSmallCode, 1500);
#ifdef _LP64 #ifdef _LP64
// Stack slots are 2X larger in LP64 than in the 32 bit VM. // Stack slots are 2X larger in LP64 than in the 32 bit VM.
define_pd_global(intx, ThreadStackSize, 1024); define_pd_global(intx, ThreadStackSize, 1024);
...@@ -71,4 +72,6 @@ define_pd_global(bool, RewriteFrequentPairs, true); ...@@ -71,4 +72,6 @@ define_pd_global(bool, RewriteFrequentPairs, true);
define_pd_global(bool, UseMembar, false); define_pd_global(bool, UseMembar, false);
// GC Ergo Flags
define_pd_global(intx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
#endif // CPU_SPARC_VM_GLOBALS_SPARC_HPP #endif // CPU_SPARC_VM_GLOBALS_SPARC_HPP
/* /*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -72,4 +72,6 @@ define_pd_global(bool, RewriteFrequentPairs, true); ...@@ -72,4 +72,6 @@ define_pd_global(bool, RewriteFrequentPairs, true);
define_pd_global(bool, UseMembar, false); define_pd_global(bool, UseMembar, false);
// GC Ergo Flags
define_pd_global(intx, CMSYoungGenPerWorker, 64*M); // default max size of CMS young gen, per GC worker thread
#endif // CPU_X86_VM_GLOBALS_X86_HPP #endif // CPU_X86_VM_GLOBALS_X86_HPP
/* /*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -293,10 +293,11 @@ void GenCollectorPolicy::initialize_size_info() { ...@@ -293,10 +293,11 @@ void GenCollectorPolicy::initialize_size_info() {
// Determine maximum size of gen0 // Determine maximum size of gen0
size_t max_new_size = 0; size_t max_new_size = 0;
if (FLAG_IS_CMDLINE(MaxNewSize)) { if (FLAG_IS_CMDLINE(MaxNewSize) || FLAG_IS_ERGO(MaxNewSize)) {
if (MaxNewSize < min_alignment()) { if (MaxNewSize < min_alignment()) {
max_new_size = min_alignment(); max_new_size = min_alignment();
} else if (MaxNewSize >= max_heap_byte_size()) { }
if (MaxNewSize >= max_heap_byte_size()) {
max_new_size = align_size_down(max_heap_byte_size() - min_alignment(), max_new_size = align_size_down(max_heap_byte_size() - min_alignment(),
min_alignment()); min_alignment());
warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or " warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or "
...@@ -333,7 +334,7 @@ void GenCollectorPolicy::initialize_size_info() { ...@@ -333,7 +334,7 @@ void GenCollectorPolicy::initialize_size_info() {
assert(max_new_size > 0, "All paths should set max_new_size"); assert(max_new_size > 0, "All paths should set max_new_size");
// Given the maximum gen0 size, determine the initial and // Given the maximum gen0 size, determine the initial and
// minimum sizes. // minimum gen0 sizes.
if (max_heap_byte_size() == min_heap_byte_size()) { if (max_heap_byte_size() == min_heap_byte_size()) {
// The maximum and minimum heap sizes are the same so // The maximum and minimum heap sizes are the same so
...@@ -396,7 +397,7 @@ void GenCollectorPolicy::initialize_size_info() { ...@@ -396,7 +397,7 @@ void GenCollectorPolicy::initialize_size_info() {
} }
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 " gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
min_gen0_size(), initial_gen0_size(), max_gen0_size()); min_gen0_size(), initial_gen0_size(), max_gen0_size());
} }
...@@ -448,7 +449,7 @@ void TwoGenerationCollectorPolicy::initialize_size_info() { ...@@ -448,7 +449,7 @@ void TwoGenerationCollectorPolicy::initialize_size_info() {
// At this point the minimum, initial and maximum sizes // At this point the minimum, initial and maximum sizes
// of the overall heap and of gen0 have been determined. // of the overall heap and of gen0 have been determined.
// The maximum gen1 size can be determined from the maximum gen0 // The maximum gen1 size can be determined from the maximum gen0
// and maximum heap size since not explicit flags exits // and maximum heap size since no explicit flags exits
// for setting the gen1 maximum. // for setting the gen1 maximum.
_max_gen1_size = max_heap_byte_size() - _max_gen0_size; _max_gen1_size = max_heap_byte_size() - _max_gen0_size;
_max_gen1_size = _max_gen1_size =
...@@ -500,7 +501,7 @@ void TwoGenerationCollectorPolicy::initialize_size_info() { ...@@ -500,7 +501,7 @@ void TwoGenerationCollectorPolicy::initialize_size_info() {
if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size, if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size,
min_heap_byte_size(), OldSize)) { min_heap_byte_size(), OldSize)) {
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 " gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
min_gen0_size(), initial_gen0_size(), max_gen0_size()); min_gen0_size(), initial_gen0_size(), max_gen0_size());
} }
...@@ -509,7 +510,7 @@ void TwoGenerationCollectorPolicy::initialize_size_info() { ...@@ -509,7 +510,7 @@ void TwoGenerationCollectorPolicy::initialize_size_info() {
if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size, if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
initial_heap_byte_size(), OldSize)) { initial_heap_byte_size(), OldSize)) {
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 " gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
min_gen0_size(), initial_gen0_size(), max_gen0_size()); min_gen0_size(), initial_gen0_size(), max_gen0_size());
} }
......
...@@ -1101,40 +1101,28 @@ void Arguments::set_cms_and_parnew_gc_flags() { ...@@ -1101,40 +1101,28 @@ void Arguments::set_cms_and_parnew_gc_flags() {
set_parnew_gc_flags(); set_parnew_gc_flags();
} }
// MaxHeapSize is aligned down in collectorPolicy
size_t max_heap = align_size_down(MaxHeapSize,
CardTableRS::ct_max_alignment_constraint());
// Now make adjustments for CMS // Now make adjustments for CMS
size_t young_gen_per_worker; intx tenuring_default = (intx)6;
intx new_ratio; size_t young_gen_per_worker = CMSYoungGenPerWorker;
size_t min_new_default;
intx tenuring_default; // Preferred young gen size for "short" pauses:
if (CMSUseOldDefaults) { // old defaults: "old" as of 6.0 // upper bound depends on # of threads and NewRatio.
if FLAG_IS_DEFAULT(CMSYoungGenPerWorker) {
FLAG_SET_ERGO(intx, CMSYoungGenPerWorker, 4*M);
}
young_gen_per_worker = 4*M;
new_ratio = (intx)15;
min_new_default = 4*M;
tenuring_default = (intx)0;
} else { // new defaults: "new" as of 6.0
young_gen_per_worker = CMSYoungGenPerWorker;
new_ratio = (intx)7;
min_new_default = 16*M;
tenuring_default = (intx)4;
}
// Preferred young gen size for "short" pauses
const uintx parallel_gc_threads = const uintx parallel_gc_threads =
(ParallelGCThreads == 0 ? 1 : ParallelGCThreads); (ParallelGCThreads == 0 ? 1 : ParallelGCThreads);
const size_t preferred_max_new_size_unaligned = const size_t preferred_max_new_size_unaligned =
ScaleForWordSize(young_gen_per_worker * parallel_gc_threads); MIN2(max_heap/(NewRatio+1), ScaleForWordSize(young_gen_per_worker * parallel_gc_threads));
const size_t preferred_max_new_size = size_t preferred_max_new_size =
align_size_up(preferred_max_new_size_unaligned, os::vm_page_size()); align_size_up(preferred_max_new_size_unaligned, os::vm_page_size());
// Unless explicitly requested otherwise, size young gen // Unless explicitly requested otherwise, size young gen
// for "short" pauses ~ 4M*ParallelGCThreads // for "short" pauses ~ CMSYoungGenPerWorker*ParallelGCThreads
// If either MaxNewSize or NewRatio is set on the command line, // If either MaxNewSize or NewRatio is set on the command line,
// assume the user is trying to set the size of the young gen. // assume the user is trying to set the size of the young gen.
if (FLAG_IS_DEFAULT(MaxNewSize) && FLAG_IS_DEFAULT(NewRatio)) { if (FLAG_IS_DEFAULT(MaxNewSize) && FLAG_IS_DEFAULT(NewRatio)) {
// Set MaxNewSize to our calculated preferred_max_new_size unless // Set MaxNewSize to our calculated preferred_max_new_size unless
...@@ -1147,49 +1135,13 @@ void Arguments::set_cms_and_parnew_gc_flags() { ...@@ -1147,49 +1135,13 @@ void Arguments::set_cms_and_parnew_gc_flags() {
} }
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty // Too early to use gclog_or_tty
tty->print_cr("Ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize); tty->print_cr("CMS ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize);
} }
// Unless explicitly requested otherwise, prefer a large
// Old to Young gen size so as to shift the collection load
// to the old generation concurrent collector
// If this is only guarded by FLAG_IS_DEFAULT(NewRatio)
// then NewSize and OldSize may be calculated. That would
// generally lead to some differences with ParNewGC for which
// there was no obvious reason. Also limit to the case where
// MaxNewSize has not been set.
FLAG_SET_ERGO(intx, NewRatio, MAX2(NewRatio, new_ratio));
// Code along this path potentially sets NewSize and OldSize // Code along this path potentially sets NewSize and OldSize
// Calculate the desired minimum size of the young gen but if assert(max_heap >= InitialHeapSize, "Error");
// NewSize has been set on the command line, use it here since assert(max_heap >= NewSize, "Error");
// it should be the final value.
size_t min_new;
if (FLAG_IS_DEFAULT(NewSize)) {
min_new = align_size_up(ScaleForWordSize(min_new_default),
os::vm_page_size());
} else {
min_new = NewSize;
}
size_t prev_initial_size = InitialHeapSize;
if (prev_initial_size != 0 && prev_initial_size < min_new + OldSize) {
FLAG_SET_ERGO(uintx, InitialHeapSize, min_new + OldSize);
// Currently minimum size and the initial heap sizes are the same.
set_min_heap_size(InitialHeapSize);
if (PrintGCDetails && Verbose) {
warning("Initial heap size increased to " SIZE_FORMAT " M from "
SIZE_FORMAT " M; use -XX:NewSize=... for finer control.",
InitialHeapSize/M, prev_initial_size/M);
}
}
// MaxHeapSize is aligned down in collectorPolicy
size_t max_heap =
align_size_down(MaxHeapSize,
CardTableRS::ct_max_alignment_constraint());
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty // Too early to use gclog_or_tty
...@@ -1198,7 +1150,11 @@ void Arguments::set_cms_and_parnew_gc_flags() { ...@@ -1198,7 +1150,11 @@ void Arguments::set_cms_and_parnew_gc_flags() {
" max_heap: " SIZE_FORMAT, " max_heap: " SIZE_FORMAT,
min_heap_size(), InitialHeapSize, max_heap); min_heap_size(), InitialHeapSize, max_heap);
} }
if (max_heap > min_new) { size_t min_new = preferred_max_new_size;
if (FLAG_IS_CMDLINE(NewSize)) {
min_new = NewSize;
}
if (max_heap > min_new && min_heap_size() > min_new) {
// Unless explicitly requested otherwise, make young gen // Unless explicitly requested otherwise, make young gen
// at least min_new, and at most preferred_max_new_size. // at least min_new, and at most preferred_max_new_size.
if (FLAG_IS_DEFAULT(NewSize)) { if (FLAG_IS_DEFAULT(NewSize)) {
...@@ -1206,18 +1162,17 @@ void Arguments::set_cms_and_parnew_gc_flags() { ...@@ -1206,18 +1162,17 @@ void Arguments::set_cms_and_parnew_gc_flags() {
FLAG_SET_ERGO(uintx, NewSize, MIN2(preferred_max_new_size, NewSize)); FLAG_SET_ERGO(uintx, NewSize, MIN2(preferred_max_new_size, NewSize));
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty // Too early to use gclog_or_tty
tty->print_cr("Ergo set NewSize: " SIZE_FORMAT, NewSize); tty->print_cr("CMS ergo set NewSize: " SIZE_FORMAT, NewSize);
} }
} }
// Unless explicitly requested otherwise, size old gen // Unless explicitly requested otherwise, size old gen
// so that it's at least 3X of NewSize to begin with; // so it's NewRatio x of NewSize.
// later NewRatio will decide how it grows; see above.
if (FLAG_IS_DEFAULT(OldSize)) { if (FLAG_IS_DEFAULT(OldSize)) {
if (max_heap > NewSize) { if (max_heap > NewSize) {
FLAG_SET_ERGO(uintx, OldSize, MIN2(3*NewSize, max_heap - NewSize)); FLAG_SET_ERGO(uintx, OldSize, MIN2(NewRatio*NewSize, max_heap - NewSize));
if (PrintGCDetails && Verbose) { if (PrintGCDetails && Verbose) {
// Too early to use gclog_or_tty // Too early to use gclog_or_tty
tty->print_cr("Ergo set OldSize: " SIZE_FORMAT, OldSize); tty->print_cr("CMS ergo set OldSize: " SIZE_FORMAT, OldSize);
} }
} }
} }
...@@ -3061,23 +3016,18 @@ jint Arguments::parse(const JavaVMInitArgs* args) { ...@@ -3061,23 +3016,18 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
} }
#ifndef KERNEL #ifndef KERNEL
if (UseConcMarkSweepGC) {
// Set flags for CMS and ParNew. Check UseConcMarkSweep first
// to ensure that when both UseConcMarkSweepGC and UseParNewGC
// are true, we don't call set_parnew_gc_flags() as well.
set_cms_and_parnew_gc_flags();
} else {
// Set heap size based on available physical memory // Set heap size based on available physical memory
set_heap_size(); set_heap_size();
// Set per-collector flags // Set per-collector flags
if (UseParallelGC || UseParallelOldGC) { if (UseParallelGC || UseParallelOldGC) {
set_parallel_gc_flags(); set_parallel_gc_flags();
} else if (UseParNewGC) { } else if (UseConcMarkSweepGC) { // should be done before ParNew check below
set_cms_and_parnew_gc_flags();
} else if (UseParNewGC) { // skipped if CMS is set above
set_parnew_gc_flags(); set_parnew_gc_flags();
} else if (UseG1GC) { } else if (UseG1GC) {
set_g1_gc_flags(); set_g1_gc_flags();
} }
}
#endif // KERNEL #endif // KERNEL
#ifdef SERIALGC #ifdef SERIALGC
......
...@@ -1540,12 +1540,8 @@ class CommandLineFlags { ...@@ -1540,12 +1540,8 @@ class CommandLineFlags {
product(bool, AlwaysPreTouch, false, \ product(bool, AlwaysPreTouch, false, \
"It forces all freshly committed pages to be pre-touched.") \ "It forces all freshly committed pages to be pre-touched.") \
\ \
product(bool, CMSUseOldDefaults, false, \ product_pd(intx, CMSYoungGenPerWorker, \
"A flag temporarily introduced to allow reverting to some " \ "The maximum size of young gen chosen by default per GC worker " \
"older default settings; older as of 6.0") \
\
product(intx, CMSYoungGenPerWorker, 16*M, \
"The amount of young gen chosen by default per GC worker " \
"thread available") \ "thread available") \
\ \
product(bool, GCOverheadReporting, false, \ product(bool, GCOverheadReporting, false, \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册