From bdbf5773a85718cfdbfc40cbed5ff6c92bf69cbc Mon Sep 17 00:00:00 2001 From: Glavo Date: Sat, 31 Oct 2026 13:59:32 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=87=AA=E5=8A=A8=E5=86=85?= =?UTF-8?q?=E5=AD=98=E5=88=86=E9=85=8D=E7=AE=97=E6=B3=95=20(#7134)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jackhuang/hmcl/game/HMCLGameInstance.java | 2 +- .../hmcl/game/HMCLGameRepository.java | 48 ++++++++++++++----- .../ui/game/IndependentSettingBinder.java | 2 +- .../org/jackhuang/hmcl/util/MathUtils.java | 2 +- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java index 1eeac883c4..42e452c400 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameInstance.java @@ -567,7 +567,7 @@ public class HMCLGameInstance extends DefaultGameInstance { maxMemory = noJVMOptions ? null : Math.toIntExact(HMCLGameRepository.getAutoAllocatedMemory( - SystemInfo.getPhysicalMemoryStatus().available(), + SystemInfo.getPhysicalMemoryStatus(), javaRuntime.getPlatform()) / 1024L / 1024L); } else { maxMemory = vs.getMaxMemory(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java index df9782243a..d228e38f6e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java @@ -19,11 +19,13 @@ import org.jackhuang.hmcl.setting.LegacyGameSettingsMigrator; import org.jackhuang.hmcl.setting.GameSettingsPresetID; import org.jackhuang.hmcl.util.FileSaver; import org.jackhuang.hmcl.util.Lang; +import org.jackhuang.hmcl.util.MathUtils; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.platform.Bits; import org.jackhuang.hmcl.util.platform.OperatingSystem; import org.jackhuang.hmcl.util.platform.Platform; +import org.jackhuang.hmcl.util.platform.hardware.PhysicalMemoryStatus; import org.jackhuang.hmcl.util.versioning.VersionNumber; import org.jetbrains.annotations.NotNullByDefault; import org.jetbrains.annotations.Nullable; @@ -496,23 +498,43 @@ public final class HMCLGameRepository extends DefaultGameRepository { } } - public static long getAutoAllocatedMemory(long available, Platform platform) { - long usable = available - 512 * 1024 * 1024; // Reserve 512 MiB memory for off-heap memory and HMCL itself - if (usable <= 0) { - return available; + public static long getAutoAllocatedMemory(PhysicalMemoryStatus memoryStatus, Platform platform) { + final long minHeapSize; + final long maxHeapSize; + + if (platform.getBits() == Bits.BIT_32) { + // https://github.com/HMCL-dev/HMCL/issues/6638 + maxHeapSize = 768 * 1024 * 1024; // 768 MiB + minHeapSize = 256 * 1024 * 1024; // 128 MiB + } else { + maxHeapSize = 24L * 1024 * 1024 * 1024; // 24 GiB + minHeapSize = 512 * 1024 * 1024; // 512 MiB } - final long threshold = 8L * 1024 * 1024 * 1024; // 8 GiB - final long suggested; - if (usable <= threshold) + // Reserve memory for off-heap memory and HMCL itself + final long reserved = 256 * 1024 * 1024; // 256 MiB + + final long threshold1 = 8L * 1024 * 1024 * 1024; // 8 GiB + final long threshold2 = 16L * 1024 * 1024 * 1024; // 16 GiB + + if (memoryStatus.total() <= minHeapSize || memoryStatus.available() < 0) { + return -1L; + } + + final long usable = Math.max( + Math.max(memoryStatus.available(), memoryStatus.total() / 16) - reserved, + 0 + ); + + long suggested; + if (usable <= threshold1) suggested = (long) (usable * 0.8); + else if (usable <= threshold2) + suggested = (long) (threshold1 * 0.8 + (usable - threshold1) * 0.4); else - suggested = Math.min( - (long) (threshold * 0.8 + (usable - threshold) * 0.2), - 16L * 1024 * 1024 * 1024); - return platform.getBits() == Bits.BIT_32 - ? Math.min(suggested, 768 * 1024 * 1024) // https://github.com/HMCL-dev/HMCL/issues/6638 - : suggested; + suggested = (long) (threshold1 * 0.8 + (threshold2 - threshold1) * 0.4 + (usable - threshold2) * 0.2); + + return MathUtils.clamp(suggested & ~0xFFFFFL, minHeapSize, maxHeapSize); } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/game/IndependentSettingBinder.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/game/IndependentSettingBinder.java index 4a2f69eba3..f6d45606c2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/game/IndependentSettingBinder.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/game/IndependentSettingBinder.java @@ -607,7 +607,7 @@ final class IndependentSettingBinder { long memoryAllocated; if (Boolean.TRUE.equals(autoMemory)) { - memoryAllocated = HMCLGameRepository.getAutoAllocatedMemory(memoryStatus.available(), Platform.SYSTEM_PLATFORM); + memoryAllocated = HMCLGameRepository.getAutoAllocatedMemory(memoryStatus, Platform.SYSTEM_PLATFORM); } else if (maxMemory != null && maxMemory > 0) { memoryAllocated = maxMemory * 1024L * 1024L; } else { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/MathUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/MathUtils.java index f71e1db8d8..041e79f4ad 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/MathUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/MathUtils.java @@ -14,7 +14,7 @@ public final class MathUtils { } /// Clamp value to fit between min and max. - public static int clamp(int value, int min, int max) { + public static long clamp(long value, long min, long max) { assert min <= max; return Math.min(max, Math.max(value, min)); }