-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Use different G1GC options for small heaps #59667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ebadyano
merged 23 commits into
elastic:master
from
ebadyano:master-ergonomics-parallelgc
Oct 6, 2020
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
7d987ba
Use the parallel collector for small heaps
ebadyano ab6059d
Merge branch 'master' of github.com:elastic/elasticsearch into master…
ebadyano 2655315
Merge branch 'master' of github.com:elastic/elasticsearch into master…
ebadyano 2003331
Addressed some comments and fixed tests.
ebadyano 3c05949
Fix precomit erorrs
ebadyano 818226a
Merge branch 'master' of github.com:elastic/elasticsearch into master…
ebadyano f14d2cd
Merge branch 'master' of github.com:elastic/elasticsearch into master…
ebadyano 4d033a4
Fix test
ebadyano 9008ede
Merge branch 'master' of github.com:elastic/elasticsearch into master…
ebadyano d0e34fe
Changed the ergonomics heuristic to use G1GC with tuned options instead
ebadyano 70b4de9
Merge branch 'master' of github.com:elastic/elasticsearch into master…
ebadyano a6f5302
fix precomit errors
ebadyano ffec016
Merge branch 'master' of github.com:elastic/elasticsearch into master…
ebadyano 80b713b
Fix precomit errors
ebadyano 411cfd4
Fix indentation
ebadyano ec2b891
Addressed Henning's and Ryan's comments.
ebadyano 8d3c734
Merge branch 'master' of github.com:elastic/elasticsearch into master…
ebadyano ac9a568
Address Henning's comments
ebadyano f326f5b
address Henning's comments
ebadyano 5ddb619
Fix tests
ebadyano d628ff9
Fix precommit tests
ebadyano d8a3840
Fix logic
ebadyano f2e999a
Add an extra test for when non G1GC policy is set
ebadyano File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,25 +53,62 @@ private JvmErgonomics() { | |
*/ | ||
static List<String> choose(final List<String> userDefinedJvmOptions) throws InterruptedException, IOException { | ||
final List<String> ergonomicChoices = new ArrayList<>(); | ||
final Map<String, Optional<String>> finalJvmOptions = finalJvmOptions(userDefinedJvmOptions); | ||
final Map<String, JvmOption> finalJvmOptions = finalJvmOptions(userDefinedJvmOptions); | ||
final long heapSize = extractHeapSize(finalJvmOptions); | ||
final long maxDirectMemorySize = extractMaxDirectMemorySize(finalJvmOptions); | ||
if (maxDirectMemorySize == 0) { | ||
ergonomicChoices.add("-XX:MaxDirectMemorySize=" + heapSize / 2); | ||
} | ||
|
||
final boolean tuneG1GCForSmallHeap = tuneG1GCForSmallHeap(heapSize); | ||
final boolean tuneG1GCHeapRegion = tuneG1GCHeapRegion(finalJvmOptions, tuneG1GCForSmallHeap); | ||
final boolean tuneG1GCInitiatingHeapOccupancyPercent = tuneG1GCInitiatingHeapOccupancyPercent(finalJvmOptions); | ||
final int tuneG1GCReservePercent = tuneG1GCReservePercent(finalJvmOptions, tuneG1GCForSmallHeap); | ||
|
||
if (tuneG1GCHeapRegion) { | ||
ergonomicChoices.add("-XX:G1HeapRegionSize=4m"); | ||
} | ||
if (tuneG1GCInitiatingHeapOccupancyPercent) { | ||
ergonomicChoices.add("-XX:InitiatingHeapOccupancyPercent=30"); | ||
} | ||
if (tuneG1GCReservePercent != 0) { | ||
ergonomicChoices.add("-XX:G1ReservePercent=" + tuneG1GCReservePercent); | ||
} | ||
|
||
return ergonomicChoices; | ||
} | ||
|
||
private static final Pattern OPTION = Pattern.compile( | ||
"^\\s*\\S+\\s+(?<flag>\\S+)\\s+:?=\\s+(?<value>\\S+)?\\s+\\{[^}]+?\\}\\s+\\{[^}]+}" | ||
"^\\s*\\S+\\s+(?<flag>\\S+)\\s+:?=\\s+(?<value>\\S+)?\\s+\\{[^}]+?\\}\\s+\\{(?<origin>[^}]+)}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Drive-by comment, feel free to ignore - should we pass |
||
); | ||
|
||
static Map<String, Optional<String>> finalJvmOptions(final List<String> userDefinedJvmOptions) throws InterruptedException, | ||
IOException { | ||
private static class JvmOption { | ||
private final String value; | ||
private final String origin; | ||
|
||
JvmOption(String value, String origin) { | ||
this.value = value; | ||
this.origin = origin; | ||
} | ||
|
||
public Optional<String> getValue() { | ||
return Optional.ofNullable(value); | ||
} | ||
|
||
public String getMandatoryValue() { | ||
return value; | ||
} | ||
|
||
public boolean isCommandLineOrigin() { | ||
return "command line".equals(this.origin); | ||
} | ||
} | ||
|
||
static Map<String, JvmOption> finalJvmOptions(final List<String> userDefinedJvmOptions) throws InterruptedException, IOException { | ||
return flagsFinal(userDefinedJvmOptions).stream() | ||
.map(OPTION::matcher) | ||
.filter(Matcher::matches) | ||
.collect(Collectors.toUnmodifiableMap(m -> m.group("flag"), m -> Optional.ofNullable(m.group("value")))); | ||
.collect(Collectors.toUnmodifiableMap(m -> m.group("flag"), m -> new JvmOption(m.group("value"), m.group("origin")))); | ||
} | ||
|
||
private static List<String> flagsFinal(final List<String> userDefinedJvmOptions) throws InterruptedException, IOException { | ||
|
@@ -116,12 +153,42 @@ private static List<String> readLinesFromInputStream(final InputStream is) throw | |
} | ||
|
||
// package private for testing | ||
static Long extractHeapSize(final Map<String, Optional<String>> finalJvmOptions) { | ||
return Long.parseLong(finalJvmOptions.get("MaxHeapSize").get()); | ||
static Long extractHeapSize(final Map<String, JvmOption> finalJvmOptions) { | ||
return Long.parseLong(finalJvmOptions.get("MaxHeapSize").getMandatoryValue()); | ||
} | ||
|
||
static long extractMaxDirectMemorySize(final Map<String, JvmOption> finalJvmOptions) { | ||
return Long.parseLong(finalJvmOptions.get("MaxDirectMemorySize").getMandatoryValue()); | ||
} | ||
|
||
// Tune G1GC options for heaps < 8GB | ||
static boolean tuneG1GCForSmallHeap(final long heapSize) { | ||
return heapSize < 8L << 30; | ||
} | ||
|
||
static boolean tuneG1GCHeapRegion(final Map<String, JvmOption> finalJvmOptions, final boolean tuneG1GCForSmallHeap) { | ||
JvmOption g1GCHeapRegion = finalJvmOptions.get("G1HeapRegionSize"); | ||
JvmOption g1GC = finalJvmOptions.get("UseG1GC"); | ||
return (tuneG1GCForSmallHeap && g1GC.getMandatoryValue().equals("true") && g1GCHeapRegion.isCommandLineOrigin() == false); | ||
} | ||
|
||
static int tuneG1GCReservePercent(final Map<String, JvmOption> finalJvmOptions, final boolean tuneG1GCForSmallHeap) { | ||
JvmOption g1GC = finalJvmOptions.get("UseG1GC"); | ||
JvmOption g1GCReservePercent = finalJvmOptions.get("G1ReservePercent"); | ||
if (g1GC.getMandatoryValue().equals("true")) { | ||
if (g1GCReservePercent.isCommandLineOrigin() == false && tuneG1GCForSmallHeap) { | ||
return 15; | ||
} else if (g1GCReservePercent.isCommandLineOrigin() == false && tuneG1GCForSmallHeap == false) { | ||
return 25; | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
static long extractMaxDirectMemorySize(final Map<String, Optional<String>> finalJvmOptions) { | ||
return Long.parseLong(finalJvmOptions.get("MaxDirectMemorySize").get()); | ||
static boolean tuneG1GCInitiatingHeapOccupancyPercent(final Map<String, JvmOption> finalJvmOptions) { | ||
JvmOption g1GC = finalJvmOptions.get("UseG1GC"); | ||
JvmOption g1GCInitiatingHeapOccupancyPercent = finalJvmOptions.get("InitiatingHeapOccupancyPercent"); | ||
return g1GCInitiatingHeapOccupancyPercent.isCommandLineOrigin() == false && g1GC.getMandatoryValue().equals("true"); | ||
} | ||
|
||
private static final Pattern SYSTEM_PROPERTY = Pattern.compile("^-D(?<key>[\\w+].*?)=(?<value>.*)$"); | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned on another channel, I think we should make reserve pct 15 rather than the default 10 - to stay safely clear of real memory circuit breaker exceptions.
I also think we should add in the IHOP always if it is not defined, just to be safe. It should not matter for performance since G1 will adaptively adjust the value.