Skip to content

Commit 5496da4

Browse files
Warn when MaxDirectMemorySize may be incorrect (Windows/JDK8 only issue) (elastic#48365)
Our JVM ergonomics extract max heap size from JDK PrintFlagsFinal output. On JDK 8, there is a system-dependent bug where memory sizes are cast to 32-bit integers. On affected systems (namely, Windows), when 1/4 of physical memory is more than the maximum integer value, the output of PrintFlagsFinal will be inaccurate. In the pathological case, where the max heap size would be a multiple of 4g, the test will fail. The practical effect of this bug, beyond test failures, is that we may set MaxDirectMemorySize to an incorrect value on Windows. This commit adds a warning about this situation during startup. On 7.4, we also warn for io.netty.allocator.type.
1 parent 90a957c commit 5496da4

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

distribution/tools/launchers/src/main/java/org/elasticsearch/tools/launchers/JvmErgonomics.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
package org.elasticsearch.tools.launchers;
2121

22+
import org.elasticsearch.tools.java_version_checker.JavaVersion;
23+
2224
import java.io.BufferedReader;
2325
import java.io.IOException;
2426
import java.io.InputStream;
@@ -58,6 +60,11 @@ static List<String> choose(final List<String> userDefinedJvmOptions) throws Inte
5860
final long heapSize = extractHeapSize(finalJvmOptions);
5961
final Map<String, String> systemProperties = extractSystemProperties(userDefinedJvmOptions);
6062
if (systemProperties.containsKey("io.netty.allocator.type") == false) {
63+
if (System.getProperty("os.name").startsWith("Windows") && JavaVersion.majorVersion(JavaVersion.CURRENT) == 8) {
64+
Launchers.errPrintln("Warning: with JDK 8 on Windows, Elasticsearch may miscalculate io.netty.allocator.type");
65+
Launchers.errPrintln(" due to a JDK issue (JDK-8074459).");
66+
Launchers.errPrintln(" Please use a newer version of Java or set io.netty.allocator.type explicitly");
67+
}
6168
if (heapSize <= 1 << 30) {
6269
ergonomicChoices.add("-Dio.netty.allocator.type=unpooled");
6370
} else {
@@ -66,6 +73,11 @@ static List<String> choose(final List<String> userDefinedJvmOptions) throws Inte
6673
}
6774
final long maxDirectMemorySize = extractMaxDirectMemorySize(finalJvmOptions);
6875
if (maxDirectMemorySize == 0) {
76+
if (System.getProperty("os.name").startsWith("Windows") && JavaVersion.majorVersion(JavaVersion.CURRENT) == 8) {
77+
Launchers.errPrintln("Warning: with JDK 8 on Windows, Elasticsearch may miscalculate MaxDirectMemorySize");
78+
Launchers.errPrintln(" due to a JDK issue (JDK-8074459).");
79+
Launchers.errPrintln(" Please use a newer version of Java or set MaxDirectMemorySize explicitly");
80+
}
6981
ergonomicChoices.add("-XX:MaxDirectMemorySize=" + heapSize / 2);
7082
}
7183
return ergonomicChoices;

distribution/tools/launchers/src/test/java/org/elasticsearch/tools/launchers/JvmErgonomicsTests.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ public void testExtractValidHeapSizeUsingMaxHeapSize() throws InterruptedExcepti
5656
}
5757

5858
public void testExtractValidHeapSizeNoOptionPresent() throws InterruptedException, IOException {
59-
// Muting on Windows, awaitsfix: https://github.com/elastic/elasticsearch/issues/47384
60-
assumeFalse(System.getProperty("os.name").startsWith("Windows"));
59+
// Muted for jdk8/Windows, see: https://github.com/elastic/elasticsearch/issues/47384
60+
assumeFalse(System.getProperty("os.name").startsWith("Windows") && JavaVersion.majorVersion(JavaVersion.CURRENT) == 8);
6161
assertThat(
6262
JvmErgonomics.extractHeapSize(JvmErgonomics.finalJvmOptions(Collections.emptyList())),
6363
greaterThan(0L));
@@ -132,6 +132,7 @@ public void testPooledMemoryChoiceOnSmallHeap() throws InterruptedException, IOE
132132
}
133133

134134
public void testPooledMemoryChoiceOnNotSmallHeap() throws InterruptedException, IOException {
135+
// Muted for jdk8/Windows, see: https://github.com/elastic/elasticsearch/issues/47384
135136
assumeFalse(System.getProperty("os.name").startsWith("Windows") && JavaVersion.majorVersion(JavaVersion.CURRENT) == 8);
136137
final String largeHeap = randomFrom(Arrays.asList("1025M", "2048M", "2G", "8G"));
137138
assertThat(
@@ -140,6 +141,7 @@ public void testPooledMemoryChoiceOnNotSmallHeap() throws InterruptedException,
140141
}
141142

142143
public void testMaxDirectMemorySizeChoice() throws InterruptedException, IOException {
144+
// Muted for jdk8/Windows, see: https://github.com/elastic/elasticsearch/issues/47384
143145
assumeFalse(System.getProperty("os.name").startsWith("Windows") && JavaVersion.majorVersion(JavaVersion.CURRENT) == 8);
144146
final Map<String, String> heapMaxDirectMemorySize = new HashMap<>();
145147
heapMaxDirectMemorySize.put("64M", Long.toString((64L << 20) / 2));

0 commit comments

Comments
 (0)