Skip to content

Commit c4c0b1a

Browse files
authored
修复自动分配内存逻辑异常的问题 (#6356)
1 parent 5e621ce commit c4c0b1a

18 files changed

Lines changed: 117 additions & 151 deletions

HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,9 @@ private InstanceGameSettingsLoadResult loadGameSettingsFile(Path file) {
382382
+ file + ", Actual: " + schemaResult.actual());
383383
case UNEXPECTED_ID -> LOG.warning("Unexpected instance game settings schema. Expected: "
384384
+ GameSettings.Instance.CURRENT_SCHEMA + ", Actual: " + schemaResult.actual());
385-
case UNSUPPORTED_MAJOR, READ_ONLY_PRESERVE_SCHEMA -> LOG.warning("Unsupported instance game settings schema. Expected: "
386-
+ GameSettings.Instance.CURRENT_SCHEMA + ", Actual: " + schemaResult.actual());
385+
case UNSUPPORTED_MAJOR, READ_ONLY_PRESERVE_SCHEMA ->
386+
LOG.warning("Unsupported instance game settings schema. Expected: "
387+
+ GameSettings.Instance.CURRENT_SCHEMA + ", Actual: " + schemaResult.actual());
387388
case READ_WRITE, READ_WRITE_PRESERVE_SCHEMA -> {
388389
}
389390
}
@@ -684,7 +685,7 @@ private void saveGameSettingsSync(String id) throws IOException {
684685

685686
/// Result of loading an instance-specific game settings file.
686687
///
687-
/// @param setting the loaded instance settings, or `null` when unavailable
688+
/// @param setting the loaded instance settings, or `null` when unavailable
688689
/// @param allowSave whether the file may be overwritten
689690
private record InstanceGameSettingsLoadResult(
690691
@Nullable GameSettings.Instance setting,
@@ -694,26 +695,31 @@ private record InstanceGameSettingsLoadResult(
694695
public LaunchOptions.Builder getLaunchOptions(String version, JavaRuntime javaVersion, Path gameDir, List<String> javaAgents, List<String> javaArguments, boolean makeLaunchScript) {
695696
GameSettings.Effective vs = getEffectiveGameSettings(version);
696697
boolean noJVMOptions = vs.getInheritable(GameSettings::noJVMOptionsProperty);
697-
boolean autoMemory = vs.get(GameSettings::autoMemoryProperty);
698+
boolean autoMemory = vs.getInheritable(GameSettings::autoMemoryProperty);
698699
GameVersionNumber gameVersionNumber = GameVersionNumber.asGameVersion(getGameVersion(version));
699700

701+
@Nullable Integer maxMemory;
702+
if (autoMemory) {
703+
maxMemory = noJVMOptions
704+
? null
705+
: Math.toIntExact(getAutoAllocatedMemory(SystemInfo.getPhysicalMemoryStatus().available()) / 1024L / 1024L);
706+
} else {
707+
maxMemory = vs.getMaxMemory();
708+
}
709+
700710
LaunchOptions.Builder builder = new LaunchOptions.Builder()
701711
.setGameDir(gameDir)
702712
.setJava(javaVersion)
703713
.setVersionType(Metadata.TITLE)
704714
.setVersionName(version)
705715
.setProfileName(Metadata.TITLE)
706-
.setGameArguments(StringUtils.tokenize(vs.get(GameSettings::gameArgumentsProperty)))
707-
.setOverrideJavaArguments(StringUtils.tokenize(vs.get(GameSettings::jvmOptionsProperty)))
708-
.setMaxMemory(noJVMOptions && autoMemory ? null : (int) (getAllocatedMemory(
709-
vs.getMaxMemory() * 1024L * 1024L,
710-
SystemInfo.getPhysicalMemoryStatus().available(),
711-
autoMemory
712-
) / 1024 / 1024))
713-
.setMinMemory(vs.get(GameSettings::minMemoryProperty))
714-
.setMetaspace(Lang.toIntOrNull(vs.get(GameSettings::permSizeProperty)))
716+
.setGameArguments(StringUtils.tokenize(vs.getInheritable(GameSettings::gameArgumentsProperty)))
717+
.setOverrideJavaArguments(StringUtils.tokenize(vs.getInheritable(GameSettings::jvmOptionsProperty)))
718+
.setMaxMemory(maxMemory)
719+
.setMinMemory(vs.getInheritable(GameSettings::minMemoryProperty))
720+
.setMetaspace(Lang.toIntOrNull(vs.getInheritable(GameSettings::permSizeProperty)))
715721
.setEnvironmentVariables(
716-
Lang.mapOf(StringUtils.tokenize(vs.get(GameSettings::environmentVariablesProperty))
722+
Lang.mapOf(StringUtils.tokenize(vs.getInheritable(GameSettings::environmentVariablesProperty))
717723
.stream()
718724
.map(it -> {
719725
int idx = it.indexOf('=');
@@ -731,16 +737,16 @@ public LaunchOptions.Builder getLaunchOptions(String version, JavaRuntime javaVe
731737
.setPostExitCommand(vs.getInheritable(GameSettings::postExitCommandProperty))
732738
.setNoGeneratedJVMArgs(noJVMOptions)
733739
.setNoGeneratedOptimizingJVMArgs(vs.getInheritable(GameSettings::noOptimizingJVMOptionsProperty))
734-
.setUseCustomNatives(vs.get(GameSettings::useCustomNativesProperty))
735-
.setNativesDir(vs.get(GameSettings::nativesDirectoryProperty))
740+
.setUseCustomNatives(vs.getInheritable(GameSettings::useCustomNativesProperty))
741+
.setNativesDir(vs.getInheritable(GameSettings::nativesDirectoryProperty))
736742
.setProcessPriority(vs.getInheritable(GameSettings::processPriorityProperty))
737743
.setGraphicsBackend(vs.getInheritable(GameSettings::graphicsBackendProperty))
738744
.setRenderer(vs.getRenderer(gameVersionNumber))
739745
.setEnableDebugLogOutput(vs.getInheritable(GameSettings::enableDebugLogOutputProperty))
740746
.setAllowAutoAgent(vs.getInheritable(GameSettings::allowAutoAgentProperty))
741747
.setDisableAutoGameOptions(vs.getInheritable(GameSettings::disableAutoGameOptionsProperty))
742-
.setUseNativeGLFW(vs.get(GameSettings::useNativeGLFWProperty))
743-
.setUseNativeOpenAL(vs.get(GameSettings::useNativeOpenALProperty))
748+
.setUseNativeGLFW(vs.getInheritable(GameSettings::useNativeGLFWProperty))
749+
.setUseNativeOpenAL(vs.getInheritable(GameSettings::useNativeOpenALProperty))
744750
.setDaemon(!makeLaunchScript && vs.getInheritable(GameSettings::launcherVisibilityProperty).isDaemon())
745751
.setJavaAgents(javaAgents)
746752
.setJavaArguments(javaArguments);
@@ -838,22 +844,21 @@ public boolean versionIdConflicts(String id) {
838844
}
839845
}
840846

841-
public static long getAllocatedMemory(long minimum, long available, boolean auto) {
842-
if (auto) {
843-
available -= 512 * 1024 * 1024; // Reserve 512 MiB memory for off-heap memory and HMCL itself
844-
if (available <= 0) {
845-
return minimum;
846-
}
847+
public static long getAutoAllocatedMemory(long available) {
848+
long usable = available - 512 * 1024 * 1024; // Reserve 512 MiB memory for off-heap memory and HMCL itself
849+
if (usable <= 0) {
850+
return available;
851+
}
847852

848-
final long threshold = 8L * 1024 * 1024 * 1024; // 8 GiB
849-
final long suggested = Math.min(available <= threshold
850-
? (long) (available * 0.8)
851-
: (long) (threshold * 0.8 + (available - threshold) * 0.2),
853+
final long threshold = 8L * 1024 * 1024 * 1024; // 8 GiB
854+
final long suggested;
855+
if (usable <= threshold)
856+
suggested = (long) (usable * 0.8);
857+
else
858+
suggested = Math.min(
859+
(long) (threshold * 0.8 + (usable - threshold) * 0.2),
852860
16L * 1024 * 1024 * 1024);
853-
return Math.max(minimum, suggested);
854-
} else {
855-
return minimum;
856-
}
861+
return suggested;
857862
}
858863

859864
public static ProxyOption getProxyOption() {

HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ else if (violatedMandatoryConstraints.contains(JavaVersionConstraint.VANILLA))
544544
}
545545

546546
if (violatedMandatoryConstraints.contains(JavaVersionConstraint.VANILLA_LINUX_JAVA_8)) {
547-
if (!setting.get(GameSettings::useCustomNativesProperty)) {
547+
if (!setting.getInheritable(GameSettings::useCustomNativesProperty)) {
548548
FXUtils.runInFX(() -> Controllers.dialog(i18n("launch.advice.vanilla_linux_java_8"), i18n("message.error"), MessageType.ERROR, breakAction));
549549
return result;
550550
} else {
@@ -581,7 +581,7 @@ else if (violatedMandatoryConstraints.contains(JavaVersionConstraint.VANILLA))
581581
}
582582

583583
// 32-bit JVM cannot make use of too much memory.
584-
if (java.getBits() == Bits.BIT_32 && setting.getMaxMemory() > 1.5 * 1024) {
584+
if (java.getBits() == Bits.BIT_32 && !setting.getInheritable(GameSettings::autoMemoryProperty) && setting.getMaxMemory() > 1.5 * 1024) {
585585
// 1.5 * 1024 is an inaccurate number.
586586
// Actual memory limit depends on operating system and memory.
587587
suggestions.add(i18n("launch.advice.too_large_memory_for_32bit"));
@@ -628,7 +628,7 @@ else if (violatedMandatoryConstraints.contains(JavaVersionConstraint.VANILLA))
628628
suggestions.add(i18n("launch.advice.modlauncher8"));
629629
break;
630630
case VANILLA_X86:
631-
if (!setting.get(GameSettings::useCustomNativesProperty)
631+
if (!setting.getInheritable(GameSettings::useCustomNativesProperty)
632632
&& Platform.isSupportedTranslationX86_64()) {
633633
suggestions.add(i18n("launch.advice.vanilla_x86.translation"));
634634
}
@@ -640,7 +640,7 @@ else if (violatedMandatoryConstraints.contains(JavaVersionConstraint.VANILLA))
640640

641641
// Cannot allocate too much memory exceeding free space.
642642
long totalMemorySizeMB = (long) MEGABYTES.convertFromBytes(SystemInfo.getTotalMemorySize());
643-
if (totalMemorySizeMB > 0 && totalMemorySizeMB < setting.getMaxMemory()) {
643+
if (totalMemorySizeMB > 0 && !setting.getInheritable(GameSettings::autoMemoryProperty) && totalMemorySizeMB < setting.getMaxMemory()) {
644644
suggestions.add(i18n("launch.advice.not_enough_space", totalMemorySizeMB));
645645
}
646646

HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,10 @@ private static Task<Void> createMcbbsPostInstallTask(HMCLGameRepository reposito
358358
GameSettings.PROPERTY_MAX_MEMORY,
359359
GameSettings.PROPERTY_PERM_SIZE
360360
));
361-
setting.autoMemoryProperty().setValue(effective.get(GameSettings::autoMemoryProperty));
362-
setting.minMemoryProperty().setValue(effective.get(GameSettings::minMemoryProperty));
361+
setting.autoMemoryProperty().setValue(effective.getInheritable(GameSettings::autoMemoryProperty));
362+
setting.minMemoryProperty().setValue(effective.getInheritable(GameSettings::minMemoryProperty));
363363
setting.maxMemoryProperty().setValue(manifest.getLaunchInfo().getMinMemory());
364-
setting.permSizeProperty().setValue(effective.get(GameSettings::permSizeProperty));
364+
setting.permSizeProperty().setValue(effective.getInheritable(GameSettings::permSizeProperty));
365365
}
366366
});
367367
}

0 commit comments

Comments
 (0)