Skip to content

Commit

Permalink
Don't drop user's MaxDirectMemorySize flag on jdk8/windows (elastic#4…
Browse files Browse the repository at this point in the history
…8657)

* Always pass user-specified MaxDirectMemorySize

We had been testing whether a user had passed a value for
MaxDirectMemorySize by parsing the output of "java -XX:PrintFlagsFinal
-version". If MaxDirectMemorySize equals zero, we set it to half of max
heap. The problem is that on Windows with JDK 8, a JDK bug incorrectly
truncates values over 4g and returns multiples of 4g as zero. In order
to always respect the user-defined settings, we need to check our input
to see if an "-XX:MaxDirectMemorySize" value has been passed.

* Always warn for Windows/jdk8 ergo issue

Even if a user has set MaxDirectMemorySize, they aren't future-proof for
this JDK bug. With this change, we issue a general warning for the
windows/JDK8 issue, and a specific warning if MaxDirectMemorySize is
unset.
  • Loading branch information
williamrandolph committed Nov 11, 2019
1 parent 69954be commit 69da652
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,20 @@ static List<String> choose(final List<String> userDefinedJvmOptions) throws Inte
final Map<String, Optional<String>> finalJvmOptions = finalJvmOptions(userDefinedJvmOptions);
final long heapSize = extractHeapSize(finalJvmOptions);
final long maxDirectMemorySize = extractMaxDirectMemorySize(finalJvmOptions);
if (maxDirectMemorySize == 0) {

if (System.getProperty("os.name").startsWith("Windows") && JavaVersion.majorVersion(JavaVersion.CURRENT) == 8) {
Launchers.errPrintln("Warning: with JDK 8 on Windows, Elasticsearch may be unable to derive correct");
Launchers.errPrintln(" ergonomic settings due to a JDK issue (JDK-8074459). Please use a newer");
Launchers.errPrintln(" version of Java.");
}

if (maxDirectMemorySize == 0 && userDefinedJvmOptions.stream().noneMatch(s -> s.startsWith("-XX:MaxDirectMemorySize"))) {

if (System.getProperty("os.name").startsWith("Windows") && JavaVersion.majorVersion(JavaVersion.CURRENT) == 8) {
Launchers.errPrintln("Warning: with JDK 8 on Windows, Elasticsearch may miscalculate MaxDirectMemorySize");
Launchers.errPrintln(" due to a JDK issue (JDK-8074459).");
Launchers.errPrintln(" Please use a newer version of Java or set MaxDirectMemorySize explicitly");
Launchers.errPrintln("Warning: MaxDirectMemorySize may have been miscalculated due to JDK-8074459.");
Launchers.errPrintln(" Please use a newer version of Java or set MaxDirectMemorySize explicitly.");
}

ergonomicChoices.add("-XX:MaxDirectMemorySize=" + heapSize / 2);
}
return ergonomicChoices;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.hamcrest.Matchers.anyOf;
Expand Down Expand Up @@ -142,8 +143,10 @@ public void testMaxDirectMemorySizeChoice() throws InterruptedException, IOExcep
}

public void testMaxDirectMemorySizeChoiceWhenSet() throws InterruptedException, IOException {
List<String> derivedSettingList = JvmErgonomics.choose(Arrays.asList("-Xms5g", "-Xmx5g", "-XX:MaxDirectMemorySize=4g"));
assertThat(
JvmErgonomics.choose(Arrays.asList("-Xms1g", "-Xmx1g", "-XX:MaxDirectMemorySize=1g")),
derivedSettingList,
// if MaxDirectMemorySize is set, we shouldn't derive our own value for it
everyItem(not(startsWith("-XX:MaxDirectMemorySize="))));
}

Expand Down

0 comments on commit 69da652

Please sign in to comment.