Default to server VM and add client VM check

Today we softly warn about running with the client VM. However, we
should really refuse to start in production mode if running with the
client VM as the performance of the client VM is too devastating for a
server application. This commit adds an option to jvm.options to ensure
that we are starting with the server VM (on all 32-bit non-Windows
platforms on server-class machines (2+ CPUs, 2+ GB physical RAM) this is
the default and on all 64-bit platforms this is the only option) and
adds a bootstrap check for the client VM.

Relates #18155
This commit is contained in:
Jason Tedor 2016-05-05 10:36:21 -04:00
parent 66e852922c
commit e11b96ca9c
4 changed files with 53 additions and 6 deletions

View File

@ -246,12 +246,6 @@ final class Bootstrap {
PidFile.create(environment.pidFile(), true);
}
// warn if running using the client VM
if (JvmInfo.jvmInfo().getVmName().toLowerCase(Locale.ROOT).contains("client")) {
ESLogger logger = Loggers.getLogger(Bootstrap.class);
logger.warn("jvm uses the client vm, make sure to run `java` with the server vm for best performance by adding `-server` to the command line");
}
try {
if (!foreground) {
Loggers.disableConsoleLogging();

View File

@ -163,6 +163,7 @@ final class BootstrapCheck {
if (Constants.LINUX) {
checks.add(new MaxMapCountCheck());
}
checks.add(new ClientJvmCheck());
return Collections.unmodifiableList(checks);
}
@ -476,4 +477,31 @@ final class BootstrapCheck {
}
static class ClientJvmCheck implements BootstrapCheck.Check {
@Override
public boolean check() {
return getVmName().toLowerCase(Locale.ROOT).contains("client");
}
// visible for testing
String getVmName() {
return JvmInfo.jvmInfo().getVmName();
}
@Override
public String errorMessage() {
return String.format(
Locale.ROOT,
"JVM is using the client VM [%s] but should be using a server VM for the best performance",
getVmName());
}
@Override
public final boolean isSystemCheck() {
return false;
}
}
}

View File

@ -31,6 +31,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.containsString;
@ -373,6 +374,27 @@ public class BootstrapCheckTests extends ESTestCase {
expectThrows(RuntimeException.class, () -> BootstrapCheck.check(true, false, defaultChecks, "testMinMasterNodes"));
}
public void testClientJvmCheck() {
final AtomicReference<String> vmName = new AtomicReference<>("Java HotSpot(TM) 32-Bit Client VM");
final BootstrapCheck.Check check = new BootstrapCheck.ClientJvmCheck() {
@Override
String getVmName() {
return vmName.get();
}
};
RuntimeException e = expectThrows(
RuntimeException.class,
() -> BootstrapCheck.check(true, false, Collections.singletonList(check), "testClientJvmCheck"));
assertThat(
e.getMessage(),
containsString("JVM is using the client VM [Java HotSpot(TM) 32-Bit Client VM] " +
"but should be using a server VM for the best performance"));
vmName.set("Java HotSpot(TM) 32-Bit Server VM");
BootstrapCheck.check(true, false, Collections.singletonList(check), "testClientJvmCheck");
}
public void testIgnoringSystemChecks() {
BootstrapCheck.Check check = new BootstrapCheck.Check() {
@Override

View File

@ -48,6 +48,9 @@
## basic
# force the server VM
-server
# set to headless, just in case
-Djava.awt.headless=true