支持禁止生成 JVM 优化参数 (#4507)

This commit is contained in:
Glavo 2025-09-18 20:04:25 +08:00 committed by GitHub
parent 8bd104c207
commit a24fea4a95
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 80 additions and 40 deletions

View File

@ -413,6 +413,7 @@ public final class HMCLGameRepository extends DefaultGameRepository {
.setPreLaunchCommand(vs.getPreLaunchCommand())
.setPostExitCommand(vs.getPostExitCommand())
.setNoGeneratedJVMArgs(vs.isNoJVMArgs())
.setNoGeneratedOptimizingJVMArgs(vs.isNoOptimizingJVMArgs())
.setNativesDirType(vs.getNativesDirType())
.setNativesDir(vs.getNativesDir())
.setProcessPriority(vs.getProcessPriority())

View File

@ -380,6 +380,20 @@ public final class VersionSetting implements Cloneable, Observable {
noJVMArgsProperty.set(noJVMArgs);
}
private final BooleanProperty noOptimizingJVMArgsProperty = new SimpleBooleanProperty(this, "noOptimizingJVMArgs", false);
public BooleanProperty noOptimizingJVMArgsProperty() {
return noOptimizingJVMArgsProperty;
}
public boolean isNoOptimizingJVMArgs() {
return noOptimizingJVMArgsProperty.get();
}
public void setNoOptimizingJVMArgs(boolean noOptimizingJVMArgs) {
noOptimizingJVMArgsProperty.set(noOptimizingJVMArgs);
}
private final BooleanProperty notCheckJVMProperty = new SimpleBooleanProperty(this, "notCheckJVM", false);
public BooleanProperty notCheckJVMProperty() {

View File

@ -43,6 +43,7 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
private final JFXTextField txtPreLaunchCommand;
private final JFXTextField txtPostExitCommand;
private final OptionToggleButton noJVMArgsPane;
private final OptionToggleButton noOptimizingJVMArgsPane;
private final OptionToggleButton noGameCheckPane;
private final OptionToggleButton noJVMCheckPane;
private final OptionToggleButton noNativesPatchPane;
@ -183,6 +184,10 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
noJVMArgsPane = new OptionToggleButton();
noJVMArgsPane.setTitle(i18n("settings.advanced.no_jvm_args"));
noOptimizingJVMArgsPane = new OptionToggleButton();
noOptimizingJVMArgsPane.setTitle(i18n("settings.advanced.no_optimizing_jvm_args"));
noOptimizingJVMArgsPane.disableProperty().bind(noJVMArgsPane.selectedProperty());
noGameCheckPane = new OptionToggleButton();
noGameCheckPane.setTitle(i18n("settings.advanced.dont_check_game_completeness"));
@ -199,7 +204,7 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
useNativeOpenALPane.setTitle(i18n("settings.advanced.use_native_openal"));
workaroundPane.getContent().setAll(
nativesDirSublist, rendererPane, noJVMArgsPane, noGameCheckPane,
nativesDirSublist, rendererPane, noJVMArgsPane, noOptimizingJVMArgsPane, noGameCheckPane,
noJVMCheckPane, noNativesPatchPane
);
@ -235,6 +240,7 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
noGameCheckPane.selectedProperty().bindBidirectional(versionSetting.notCheckGameProperty());
noJVMCheckPane.selectedProperty().bindBidirectional(versionSetting.notCheckJVMProperty());
noJVMArgsPane.selectedProperty().bindBidirectional(versionSetting.noJVMArgsProperty());
noOptimizingJVMArgsPane.selectedProperty().bindBidirectional(versionSetting.noOptimizingJVMArgsProperty());
noNativesPatchPane.selectedProperty().bindBidirectional(versionSetting.notPatchNativesProperty());
useNativeGLFWPane.selectedProperty().bindBidirectional(versionSetting.useNativeGLFWProperty());
useNativeOpenALPane.selectedProperty().bindBidirectional(versionSetting.useNativeOpenALProperty());
@ -276,6 +282,7 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
noGameCheckPane.selectedProperty().unbindBidirectional(versionSetting.notCheckGameProperty());
noJVMCheckPane.selectedProperty().unbindBidirectional(versionSetting.notCheckJVMProperty());
noJVMArgsPane.selectedProperty().unbindBidirectional(versionSetting.noJVMArgsProperty());
noOptimizingJVMArgsPane.selectedProperty().unbindBidirectional(versionSetting.noOptimizingJVMArgsProperty());
noNativesPatchPane.selectedProperty().unbindBidirectional(versionSetting.notPatchNativesProperty());
useNativeGLFWPane.selectedProperty().unbindBidirectional(versionSetting.useNativeGLFWProperty());
useNativeOpenALPane.selectedProperty().unbindBidirectional(versionSetting.useNativeOpenALProperty());

View File

@ -1290,6 +1290,7 @@ settings.advanced.natives_directory.hint=This option is intended only for users
Before proceeding, please make sure all libraries (e.g. lwjgl.dll, libopenal.so) are provided in your desired directory.\n\
Note: It is recommended to use a fully English-letters path for the specified local library file. Otherwise it may lead to game launch failure.
settings.advanced.no_jvm_args=Do not add default JVM arguments
settings.advanced.no_optimizing_jvm_args=Do not add default JVM optimization arguments
settings.advanced.precall_command=Pre-launch Command
settings.advanced.precall_command.prompt=Commands to execute before the game launches
settings.advanced.process_priority=Process Priority

View File

@ -1080,6 +1080,7 @@ settings.advanced.natives_directory.default=預設 (由啟動器提供遊戲本
settings.advanced.natives_directory.default.version_id=<實例名稱>
settings.advanced.natives_directory.hint=本選項提供給 Apple Silicon 等未受遊戲官方支援的平台來自訂遊戲本機庫。如果你不知道本選項的含義,請你不要修改本選項,否則會導致遊戲無法啟動。\n\n如果你要修改本選項你需要保證自訂目錄下有遊戲所需的本機庫檔案如 lwjgl.dll (liblwjgl.so), openal.dll (libopenal.so) 等檔案。啟動器不會幫你補全缺少的本機庫檔案。\n\n注意建議指定的本機庫檔案路徑使用全英文字元否則可能導致遊戲啟動失敗。
settings.advanced.no_jvm_args=不新增預設的 Java 虛擬機參數
settings.advanced.no_optimizing_jvm_args=不自動添加 Java 虛擬機優化參數
settings.advanced.precall_command=遊戲啟動前執行指令
settings.advanced.precall_command.prompt=將在遊戲啟動前呼叫使用
settings.advanced.process_priority=處理程式優先度

View File

@ -1091,6 +1091,7 @@ settings.advanced.natives_directory.default=默认 (由启动器提供游戏本
settings.advanced.natives_directory.default.version_id=<实例名称>
settings.advanced.natives_directory.hint=本选项提供给 Apple Silicon 等未受游戏官方支持的平台来自定义游戏本地库。如果你不知道本选项的含义,请不要修改本选项,否则会导致游戏无法启动!\n\n如果你要修改本选项你需要保证自定义文件夹下有游戏所需的本地库文件如 lwjgl.dll (liblwjgl.so)、openal.dll (libopenal.so) 等文件。启动器不会帮你补全缺少的本地库文件!\n\n注意指定的本地库文件路径建议只包含英文大小写字母、数字和下划线否则可能会导致启动游戏失败。
settings.advanced.no_jvm_args=不添加默认的 Java 虚拟机参数
settings.advanced.no_optimizing_jvm_args=不自动添加 Java 虚拟机优化参数
settings.advanced.precall_command=游戏启动前执行命令
settings.advanced.precall_command.prompt=将在游戏启动前调用
settings.advanced.process_priority=进程优先级

View File

@ -55,6 +55,7 @@ public class LaunchOptions implements Serializable {
private String proxyUser;
private String proxyPass;
private boolean noGeneratedJVMArgs;
private boolean noGeneratedOptimizingJVMArgs;
private String preLaunchCommand;
private String postExitCommand;
private NativesDirectoryType nativesDirType;
@ -226,6 +227,13 @@ public class LaunchOptions implements Serializable {
return noGeneratedJVMArgs;
}
/**
* Prevent game launcher from generating optimizing JVM arguments.
*/
public boolean isNoGeneratedOptimizingJVMArgs() {
return noGeneratedOptimizingJVMArgs;
}
/**
* Command called before game launches.
*/
@ -281,7 +289,7 @@ public class LaunchOptions implements Serializable {
return daemon;
}
public static class Builder {
public static final class Builder {
private final LaunchOptions options = new LaunchOptions();
@ -439,6 +447,11 @@ public class LaunchOptions implements Serializable {
return this;
}
public Builder setNoGeneratedOptimizingJVMArgs(boolean noGeneratedOptimizingJVMArgs) {
options.noGeneratedOptimizingJVMArgs = noGeneratedOptimizingJVMArgs;
return this;
}
public Builder setPreLaunchCommand(String preLaunchCommand) {
options.preLaunchCommand = preLaunchCommand;
return this;

View File

@ -193,50 +193,52 @@ public class DefaultLauncher extends Launcher {
final int javaVersion = options.getJava().getParsedVersion();
final boolean is64bit = options.getJava().getBits() == Bits.BIT_64;
res.addUnstableDefault("UnlockExperimentalVMOptions", true);
res.addUnstableDefault("UnlockDiagnosticVMOptions", true);
if (!options.isNoGeneratedOptimizingJVMArgs()) {
res.addUnstableDefault("UnlockExperimentalVMOptions", true);
res.addUnstableDefault("UnlockDiagnosticVMOptions", true);
// Using G1GC with its settings by default
if (javaVersion >= 8
&& res.noneMatch(arg -> "-XX:-UseG1GC".equals(arg) || (arg.startsWith("-XX:+Use") && arg.endsWith("GC")))) {
res.addUnstableDefault("UseG1GC", true);
res.addUnstableDefault("G1MixedGCCountTarget", "5");
res.addUnstableDefault("G1NewSizePercent", "20");
res.addUnstableDefault("G1ReservePercent", "20");
res.addUnstableDefault("MaxGCPauseMillis", "50");
res.addUnstableDefault("G1HeapRegionSize", "32m");
}
res.addUnstableDefault("OmitStackTraceInFastThrow", false);
// JIT Options
if (javaVersion <= 8) {
res.addUnstableDefault("MaxInlineLevel", "15");
}
if (is64bit && SystemInfo.getTotalMemorySize() > 4L * 1024 * 1024 * 1024) {
res.addUnstableDefault("DontCompileHugeMethods", false);
res.addUnstableDefault("MaxNodeLimit", "240000");
res.addUnstableDefault("NodeLimitFudgeFactor", "8000");
res.addUnstableDefault("TieredCompileTaskTimeout", "10000");
res.addUnstableDefault("ReservedCodeCacheSize", "400M");
if (javaVersion >= 9) {
res.addUnstableDefault("NonNMethodCodeHeapSize", "12M");
res.addUnstableDefault("ProfiledCodeHeapSize", "194M");
// Using G1GC with its settings by default
if (javaVersion >= 8
&& res.noneMatch(arg -> "-XX:-UseG1GC".equals(arg) || (arg.startsWith("-XX:+Use") && arg.endsWith("GC")))) {
res.addUnstableDefault("UseG1GC", true);
res.addUnstableDefault("G1MixedGCCountTarget", "5");
res.addUnstableDefault("G1NewSizePercent", "20");
res.addUnstableDefault("G1ReservePercent", "20");
res.addUnstableDefault("MaxGCPauseMillis", "50");
res.addUnstableDefault("G1HeapRegionSize", "32m");
}
if (javaVersion >= 8) {
res.addUnstableDefault("NmethodSweepActivity", "1");
res.addUnstableDefault("OmitStackTraceInFastThrow", false);
// JIT Options
if (javaVersion <= 8) {
res.addUnstableDefault("MaxInlineLevel", "15");
}
}
if (is64bit && SystemInfo.getTotalMemorySize() > 4L * 1024 * 1024 * 1024) {
res.addUnstableDefault("DontCompileHugeMethods", false);
res.addUnstableDefault("MaxNodeLimit", "240000");
res.addUnstableDefault("NodeLimitFudgeFactor", "8000");
res.addUnstableDefault("TieredCompileTaskTimeout", "10000");
res.addUnstableDefault("ReservedCodeCacheSize", "400M");
if (javaVersion >= 9) {
res.addUnstableDefault("NonNMethodCodeHeapSize", "12M");
res.addUnstableDefault("ProfiledCodeHeapSize", "194M");
}
if (is64bit && javaVersion == 25) {
res.addUnstableDefault("UseCompactObjectHeaders", true);
}
if (javaVersion >= 8) {
res.addUnstableDefault("NmethodSweepActivity", "1");
}
}
// 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.
if (!is64bit) {
res.addDefault("-Xss", "1m");
if (is64bit && javaVersion == 25) {
res.addUnstableDefault("UseCompactObjectHeaders", true);
}
// 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.
if (!is64bit) {
res.addDefault("-Xss", "1m");
}
}
if (javaVersion == 16)