用户 JVM 参数优先于默认参数 (#903)
* close #885: use the GC selected by user by default * fix: default JVM args conflict with user args * Options take precedence over JVM args * compile huge methods by default * update settings.advanced.jvm_args text * Using JVM args suppression options * update settings.advanced.jvm_args text
This commit is contained in:
@@ -364,7 +364,7 @@ settings.advanced.dont_check_jvm_validity=Don't check whether JVM can launch the
|
|||||||
settings.advanced.game_dir.default=Standard (.minecraft/)
|
settings.advanced.game_dir.default=Standard (.minecraft/)
|
||||||
settings.advanced.game_dir.independent=Independent (.minecraft/versions/<version name>/, except for assets and libraries)
|
settings.advanced.game_dir.independent=Independent (.minecraft/versions/<version name>/, except for assets and libraries)
|
||||||
settings.advanced.java_permanent_generation_space=PermGen Space/MB
|
settings.advanced.java_permanent_generation_space=PermGen Space/MB
|
||||||
settings.advanced.jvm_args=Java VM Arguments
|
settings.advanced.jvm_args=Java VM Arguments (overriding defaults)
|
||||||
settings.advanced.launcher_visibility.close=Close the launcher when the game launched.
|
settings.advanced.launcher_visibility.close=Close the launcher when the game launched.
|
||||||
settings.advanced.launcher_visibility.hide=Hide the launcher when the game launched.
|
settings.advanced.launcher_visibility.hide=Hide the launcher when the game launched.
|
||||||
settings.advanced.launcher_visibility.hide_and_reopen=Hide the launcher and re-open when game closes.
|
settings.advanced.launcher_visibility.hide_and_reopen=Hide the launcher and re-open when game closes.
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ settings.advanced.dont_check_jvm_validity=No verificar si JVM puede lanzar el ju
|
|||||||
settings.advanced.game_dir.default=Por defecto (.minecraft/)
|
settings.advanced.game_dir.default=Por defecto (.minecraft/)
|
||||||
settings.advanced.game_dir.independent=Independiente (.minecraft/versions/<version name>/, excepto assets,libraries)
|
settings.advanced.game_dir.independent=Independiente (.minecraft/versions/<version name>/, excepto assets,libraries)
|
||||||
settings.advanced.java_permanent_generation_space=PermGen Space/MB
|
settings.advanced.java_permanent_generation_space=PermGen Space/MB
|
||||||
settings.advanced.jvm_args=Java VM Arguments
|
settings.advanced.jvm_args=Java VM Arguments (overriding defaults)
|
||||||
settings.advanced.launcher_visibility.close=Cerrar launcher cuando juego es iniciado.
|
settings.advanced.launcher_visibility.close=Cerrar launcher cuando juego es iniciado.
|
||||||
settings.advanced.launcher_visibility.hide=Esconder launcher cuando juego is iniciado.
|
settings.advanced.launcher_visibility.hide=Esconder launcher cuando juego is iniciado.
|
||||||
settings.advanced.launcher_visibility.hide_and_reopen=Esconder launcher y reabrir cuando juego cierre.
|
settings.advanced.launcher_visibility.hide_and_reopen=Esconder launcher y reabrir cuando juego cierre.
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ settings.advanced.dont_check_jvm_validity=不檢查 JVM 與遊戲的相容性
|
|||||||
settings.advanced.game_dir.default=預設(.minecraft/)
|
settings.advanced.game_dir.default=預設(.minecraft/)
|
||||||
settings.advanced.game_dir.independent=各版本獨立(.minecraft/versions/<版本名>/,除 assets、libraries)
|
settings.advanced.game_dir.independent=各版本獨立(.minecraft/versions/<版本名>/,除 assets、libraries)
|
||||||
settings.advanced.java_permanent_generation_space=記憶體永久儲存區域(不必填寫,格式: MB)
|
settings.advanced.java_permanent_generation_space=記憶體永久儲存區域(不必填寫,格式: MB)
|
||||||
settings.advanced.jvm_args=Java 虛擬機參數(不必填寫)
|
settings.advanced.jvm_args=Java 虛擬機參數(不必填寫,覆蓋默認設置)
|
||||||
settings.advanced.launcher_visibility.close=遊戲啟動後結束啟動器
|
settings.advanced.launcher_visibility.close=遊戲啟動後結束啟動器
|
||||||
settings.advanced.launcher_visibility.hide=遊戲啟動後隱藏啟動器
|
settings.advanced.launcher_visibility.hide=遊戲啟動後隱藏啟動器
|
||||||
settings.advanced.launcher_visibility.hide_and_reopen=隱藏啟動器並在遊戲結束後重新開啟
|
settings.advanced.launcher_visibility.hide_and_reopen=隱藏啟動器並在遊戲結束後重新開啟
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ settings.advanced.dont_check_jvm_validity=不检查 JVM 与游戏的兼容性
|
|||||||
settings.advanced.game_dir.default=默认(.minecraft/)
|
settings.advanced.game_dir.default=默认(.minecraft/)
|
||||||
settings.advanced.game_dir.independent=各版本独立(.minecraft/versions/<版本名>/,除 assets、libraries)
|
settings.advanced.game_dir.independent=各版本独立(.minecraft/versions/<版本名>/,除 assets、libraries)
|
||||||
settings.advanced.java_permanent_generation_space=内存永久保存区域(不必填写,单位 MB)
|
settings.advanced.java_permanent_generation_space=内存永久保存区域(不必填写,单位 MB)
|
||||||
settings.advanced.jvm_args=Java 虚拟机参数(不必填写)
|
settings.advanced.jvm_args=Java 虚拟机参数(不必填写,覆盖默认设置)
|
||||||
settings.advanced.launcher_visibility.close=游戏启动后结束启动器
|
settings.advanced.launcher_visibility.close=游戏启动后结束启动器
|
||||||
settings.advanced.launcher_visibility.hide=游戏启动后隐藏启动器
|
settings.advanced.launcher_visibility.hide=游戏启动后隐藏启动器
|
||||||
settings.advanced.launcher_visibility.hide_and_reopen=隐藏启动器并在游戏结束后重新打开
|
settings.advanced.launcher_visibility.hide_and_reopen=隐藏启动器并在游戏结束后重新打开
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ import static org.jackhuang.hmcl.util.Lang.mapOf;
|
|||||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
*/
|
*/
|
||||||
public class DefaultLauncher extends Launcher {
|
public class DefaultLauncher extends Launcher {
|
||||||
@@ -84,53 +83,63 @@ public class DefaultLauncher extends Launcher {
|
|||||||
if (!options.isNoGeneratedJVMArgs()) {
|
if (!options.isNoGeneratedJVMArgs()) {
|
||||||
appendJvmArgs(res);
|
appendJvmArgs(res);
|
||||||
|
|
||||||
res.add("-Dminecraft.client.jar=" + repository.getVersionJar(version));
|
res.addDefault("-Dminecraft.client.jar=", repository.getVersionJar(version).toString());
|
||||||
|
|
||||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.OSX) {
|
if (OperatingSystem.CURRENT_OS == OperatingSystem.OSX) {
|
||||||
res.add("-Xdock:name=Minecraft " + version.getId());
|
res.addDefault("-Xdock:name=", "Minecraft " + version.getId());
|
||||||
res.add("-Xdock:icon=" + repository.getAssetObject(version.getId(), version.getAssetIndex().getId(), "icons/minecraft.icns").getAbsolutePath());
|
res.addDefault("-Xdock:icon=", repository.getAssetObject(version.getId(), version.getAssetIndex().getId(), "icons/minecraft.icns").getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OperatingSystem.CURRENT_OS != OperatingSystem.WINDOWS)
|
if (OperatingSystem.CURRENT_OS != OperatingSystem.WINDOWS)
|
||||||
res.add("-Duser.home=" + options.getGameDir().getParent());
|
res.addDefault("-Duser.home=", options.getGameDir().getParent());
|
||||||
|
|
||||||
// Force using G1GC with its settings
|
// Using G1GC with its settings by default
|
||||||
if (options.getJava().getParsedVersion() >= JavaVersion.JAVA_8) {
|
if (options.getJava().getParsedVersion() >= JavaVersion.JAVA_8) {
|
||||||
res.add("-XX:+UnlockExperimentalVMOptions");
|
boolean addG1Args = true;
|
||||||
res.add("-XX:+UseG1GC");
|
for (String javaArg : options.getJavaArguments()) {
|
||||||
res.add("-XX:G1NewSizePercent=20");
|
if ("-XX:-UseG1GC".equals(javaArg) || (javaArg.startsWith("-XX:+Use") && javaArg.endsWith("GC"))) {
|
||||||
res.add("-XX:G1ReservePercent=20");
|
addG1Args = false;
|
||||||
res.add("-XX:MaxGCPauseMillis=50");
|
break;
|
||||||
res.add("-XX:G1HeapRegionSize=16M");
|
}
|
||||||
|
}
|
||||||
|
if (addG1Args) {
|
||||||
|
res.addUnstableDefault("UnlockExperimentalVMOptions", true);
|
||||||
|
res.addUnstableDefault("UseG1GC", true);
|
||||||
|
res.addUnstableDefault("G1NewSizePercent", "20");
|
||||||
|
res.addUnstableDefault("G1ReservePercent", "20");
|
||||||
|
res.addUnstableDefault("MaxGCPauseMillis", "50");
|
||||||
|
res.addUnstableDefault("G1HeapRegionSize", "16m");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.getMetaspace() != null && options.getMetaspace() > 0)
|
if (options.getMetaspace() != null && options.getMetaspace() > 0)
|
||||||
if (options.getJava().getParsedVersion() < JavaVersion.JAVA_8)
|
if (options.getJava().getParsedVersion() < JavaVersion.JAVA_8)
|
||||||
res.add("-XX:PermSize= " + options.getMetaspace() + "m");
|
res.addDefault("-XX:PermSize=", options.getMetaspace() + "m");
|
||||||
else
|
else
|
||||||
res.add("-XX:MetaspaceSize=" + options.getMetaspace() + "m");
|
res.addDefault("-XX:MetaspaceSize=", options.getMetaspace() + "m");
|
||||||
|
|
||||||
res.add("-XX:-UseAdaptiveSizePolicy");
|
res.addUnstableDefault("UseAdaptiveSizePolicy", false);
|
||||||
res.add("-XX:-OmitStackTraceInFastThrow");
|
res.addUnstableDefault("OmitStackTraceInFastThrow", false);
|
||||||
res.add("-Xmn128m");
|
res.addUnstableDefault("DontCompileHugeMethods", false);
|
||||||
|
res.addDefault("-Xmn", "128m");
|
||||||
|
|
||||||
// As 32-bit JVM allocate 320KB for stack by default rather than 64-bit version allocating 1MB,
|
// As 32-bit JVM allocate 320KB for stack by default rather than 64-bit version allocating 1MB,
|
||||||
// causing Minecraft 1.13 crashed accounting for java.lang.StackOverflowError.
|
// causing Minecraft 1.13 crashed accounting for java.lang.StackOverflowError.
|
||||||
if (options.getJava().getPlatform() == Platform.BIT_32) {
|
if (options.getJava().getPlatform() == Platform.BIT_32) {
|
||||||
res.add("-Xss1M");
|
res.addDefault("-Xss", "1m");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.getMaxMemory() != null && options.getMaxMemory() > 0)
|
if (options.getMaxMemory() != null && options.getMaxMemory() > 0)
|
||||||
res.add("-Xmx" + options.getMaxMemory() + "m");
|
res.addDefault("-Xmx", options.getMaxMemory() + "m");
|
||||||
|
|
||||||
if (options.getMinMemory() != null && options.getMinMemory() > 0)
|
if (options.getMinMemory() != null && options.getMinMemory() > 0)
|
||||||
res.add("-Xms" + options.getMinMemory() + "m");
|
res.addDefault("-Xms", options.getMinMemory() + "m");
|
||||||
|
|
||||||
if (options.getJava().getParsedVersion() == JavaVersion.JAVA_16)
|
if (options.getJava().getParsedVersion() == JavaVersion.JAVA_16)
|
||||||
res.add("--illegal-access=permit");
|
res.addDefault("--illegal-access=", "permit");
|
||||||
|
|
||||||
res.add("-Dfml.ignoreInvalidMinecraftCertificates=true");
|
res.addDefault("-Dfml.ignoreInvalidMinecraftCertificates=", "true");
|
||||||
res.add("-Dfml.ignorePatchDiscrepancies=true");
|
res.addDefault("-Dfml.ignorePatchDiscrepancies=", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
Proxy proxy = options.getProxy();
|
Proxy proxy = options.getProxy();
|
||||||
@@ -140,13 +149,13 @@ public class DefaultLauncher extends Launcher {
|
|||||||
String host = address.getHostString();
|
String host = address.getHostString();
|
||||||
int port = address.getPort();
|
int port = address.getPort();
|
||||||
if (proxy.type() == Proxy.Type.HTTP) {
|
if (proxy.type() == Proxy.Type.HTTP) {
|
||||||
res.add("-Dhttp.proxyHost=" + host);
|
res.addDefault("-Dhttp.proxyHost=", host);
|
||||||
res.add("-Dhttp.proxyPort=" + port);
|
res.addDefault("-Dhttp.proxyPort=", String.valueOf(port));
|
||||||
res.add("-Dhttps.proxyHost=" + host);
|
res.addDefault("-Dhttps.proxyHost=", host);
|
||||||
res.add("-Dhttps.proxyPort=" + port);
|
res.addDefault("-Dhttps.proxyPort=", String.valueOf(port));
|
||||||
} else if (proxy.type() == Proxy.Type.SOCKS) {
|
} else if (proxy.type() == Proxy.Type.SOCKS) {
|
||||||
res.add("-DsocksProxyHost=" + host);
|
res.addDefault("-DsocksProxyHost=", host);
|
||||||
res.add("-DsocksProxyPort=" + port);
|
res.addDefault("-DsocksProxyPort=", String.valueOf(port));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,15 +19,20 @@ package org.jackhuang.hmcl.util.platform;
|
|||||||
|
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||||
|
|
||||||
public final class CommandBuilder {
|
public final class CommandBuilder {
|
||||||
|
private static final Pattern UNSTABLE_OPTION_PATTERN = Pattern.compile("-XX:(?<key>[a-zA-Z0-9]+)=(?<value>.*)");
|
||||||
|
private static final Pattern UNSTABLE_BOOLEAN_OPTION_PATTERN = Pattern.compile("-XX:(?<value>[+\\-])(?<key>[a-zA-Z0-9]+)");
|
||||||
|
|
||||||
private final OperatingSystem os;
|
private final OperatingSystem os;
|
||||||
private List<Item> raw = new LinkedList<>();
|
private final List<Item> raw = new LinkedList<>();
|
||||||
|
|
||||||
public CommandBuilder() {
|
public CommandBuilder() {
|
||||||
this(OperatingSystem.CURRENT_OS);
|
this(OperatingSystem.CURRENT_OS);
|
||||||
@@ -75,13 +80,66 @@ public final class CommandBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandBuilder addDefault(String opt) {
|
||||||
|
for (Item item : raw) {
|
||||||
|
if (item.arg.equals(opt)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
raw.add(new Item(opt, true));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandBuilder addDefault(String opt, String value) {
|
||||||
|
for (Item item : raw) {
|
||||||
|
if (item.arg.startsWith(opt)) {
|
||||||
|
LOG.info("Default option '" + opt + value + "' is suppressed by '" + item.arg + "'");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
raw.add(new Item(opt + value, true));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandBuilder addUnstableDefault(String opt, boolean value) {
|
||||||
|
for (Item item : raw) {
|
||||||
|
final Matcher matcher = UNSTABLE_BOOLEAN_OPTION_PATTERN.matcher(item.arg);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
if (matcher.group("key").equals(opt)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
raw.add(new Item("-XX:+" + opt, true));
|
||||||
|
} else {
|
||||||
|
raw.add(new Item("-XX:-" + opt, true));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandBuilder addUnstableDefault(String opt, String value) {
|
||||||
|
for (Item item : raw) {
|
||||||
|
final Matcher matcher = UNSTABLE_OPTION_PATTERN.matcher(item.arg);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
if (matcher.group("key").equals(opt)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
raw.add(new Item("-XX:" + opt + "=" + value, true));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean removeIf(Predicate<String> pred) {
|
public boolean removeIf(Predicate<String> pred) {
|
||||||
return raw.removeIf(i -> pred.test(i.arg));
|
return raw.removeIf(i -> pred.test(i.arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.join(" ", raw.stream().map(i -> i.parse ? parse(i.arg) : i.arg).collect(Collectors.toList()));
|
return raw.stream().map(i -> i.parse ? parse(i.arg) : i.arg).collect(Collectors.joining(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> asList() {
|
public List<String> asList() {
|
||||||
|
|||||||
Reference in New Issue
Block a user