From 575be16d3e0c967a29a58185169870fe1d9a88b5 Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Tue, 14 Apr 2026 12:47:48 +0500 Subject: [PATCH 1/4] fix(EnsureAvailableMemory): do not warn if available memory could not be read Signed-off-by: Octol1ttle --- launcher/minecraft/launch/EnsureAvailableMemory.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/launcher/minecraft/launch/EnsureAvailableMemory.cpp b/launcher/minecraft/launch/EnsureAvailableMemory.cpp index a0e156770..6605f0ce8 100644 --- a/launcher/minecraft/launch/EnsureAvailableMemory.cpp +++ b/launcher/minecraft/launch/EnsureAvailableMemory.cpp @@ -26,9 +26,11 @@ EnsureAvailableMemory::EnsureAvailableMemory(LaunchTask* parent, MinecraftInstan void EnsureAvailableMemory::executeTask() { const uint64_t available = HardwareInfo::availableRamMiB(); - const uint64_t min = m_instance->settings()->get("MinMemAlloc").toUInt(); - const uint64_t max = m_instance->settings()->get("MaxMemAlloc").toUInt(); - const uint64_t required = std::max(min, max); + if (available == 0) { + // could not read + emitSucceeded(); + return; + } if (static_cast(required) * 0.9 > static_cast(available)) { bool shouldAbort = false; From ae331cfc9af3b5eb5148167e0a2142057c255978 Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Tue, 14 Apr 2026 18:43:52 +0500 Subject: [PATCH 2/4] change(EnsureAvailableMemory): rephrase warning message Signed-off-by: Octol1ttle --- .../launch/EnsureAvailableMemory.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/launcher/minecraft/launch/EnsureAvailableMemory.cpp b/launcher/minecraft/launch/EnsureAvailableMemory.cpp index 6605f0ce8..cb7a04ab1 100644 --- a/launcher/minecraft/launch/EnsureAvailableMemory.cpp +++ b/launcher/minecraft/launch/EnsureAvailableMemory.cpp @@ -32,17 +32,22 @@ void EnsureAvailableMemory::executeTask() return; } - if (static_cast(required) * 0.9 > static_cast(available)) { + const uint64_t settingMin = m_instance->settings()->get("MinMemAlloc").toUInt(); + const uint64_t settingMax = m_instance->settings()->get("MaxMemAlloc").toUInt(); + const uint64_t max = std::max(settingMin, settingMax); + + if (static_cast(max) * 0.9 > static_cast(available)) { bool shouldAbort = false; if (m_instance->settings()->get("LowMemWarning").toBool()) { auto* dialog = CustomMessageBox::selectable( - nullptr, tr("Not enough RAM"), - tr("There is not enough RAM available to launch this instance with the current memory settings.\n\n" - "Required: %1 MiB\nAvailable: %2 MiB\n\n" - "Continue anyway? This may cause slowdowns in the game and your system.") - .arg(required) - .arg(available), + nullptr, tr("Low free memory"), + tr("There might not be enough free RAM to launch this instance with the current memory settings.\n\n" + "Maximum allocated: %1 MiB\nFree: %2 MiB (out of %3 MiB total)\n\n" + "Launch anyway? This may cause slowdowns in the game and your system.") + .arg(max) + .arg(available) + .arg(HardwareInfo::totalRamMiB()), QMessageBox::Icon::Warning, QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, QMessageBox::StandardButton::No); From 0b578fa767119427b84d8d42440d4cdc50aedcbe Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Tue, 14 Apr 2026 18:44:53 +0500 Subject: [PATCH 3/4] fix(EnsureAvailableMemory/macOS): warn based on memory pressure rather than available RAM Signed-off-by: Octol1ttle --- launcher/HardwareInfo.cpp | 33 ++++++++++----- launcher/HardwareInfo.h | 13 ++++++ .../launch/EnsureAvailableMemory.cpp | 42 +++++++++++++++++++ .../minecraft/launch/PrintInstanceInfo.cpp | 5 +++ 4 files changed, 83 insertions(+), 10 deletions(-) diff --git a/launcher/HardwareInfo.cpp b/launcher/HardwareInfo.cpp index 5937c33bc..3e20cc19b 100644 --- a/launcher/HardwareInfo.cpp +++ b/launcher/HardwareInfo.cpp @@ -141,7 +141,6 @@ uint64_t HardwareInfo::availableRamMiB() } #elif defined(Q_OS_MACOS) -#include "mach/mach.h" #include "sys/sysctl.h" QString HardwareInfo::cpuInfo() @@ -171,18 +170,32 @@ uint64_t HardwareInfo::totalRamMiB() uint64_t HardwareInfo::availableRamMiB() { - mach_port_t host_port = mach_host_self(); - mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; + return 0; +} - vm_statistics64_data_t vm_stats; - - if (host_statistics64(host_port, HOST_VM_INFO64, reinterpret_cast(&vm_stats), &count) == KERN_SUCCESS) { - // transforming bytes -> mib - return (vm_stats.free_count + vm_stats.inactive_count) * vm_page_size / 1024 / 1024; +MacOSHardwareInfo::MemoryPressureLevel MacOSHardwareInfo::memoryPressureLevel() +{ + uint32_t level; + size_t levelSize = sizeof level; + if (sysctlbyname("kern.memorystatus_vm_pressure_level", &level, &levelSize, nullptr, 0) == 0) { + return static_cast(level); } - qWarning() << "Could not get available RAM: host_statistics64"; - return 0; + qWarning() << "Could not get memory pressure level: sysctlbyname"; + return MemoryPressureLevel::Normal; +} + +QString MacOSHardwareInfo::memoryPressureLevelName() +{ + // The names are internal, users refer to levels by their graph colors in Activity Monitor + switch (memoryPressureLevel()) { + case MemoryPressureLevel::Normal: + return "Green"; + case MemoryPressureLevel::Warning: + return "Yellow"; + case MemoryPressureLevel::Critical: + return "Red"; + } } #elif defined(Q_OS_LINUX) diff --git a/launcher/HardwareInfo.h b/launcher/HardwareInfo.h index 00e19f214..4efd339b6 100644 --- a/launcher/HardwareInfo.h +++ b/launcher/HardwareInfo.h @@ -27,3 +27,16 @@ uint64_t totalRamMiB(); uint64_t availableRamMiB(); QStringList gpuInfo(); } // namespace HardwareInfo + +#ifdef Q_OS_MACOS +namespace MacOSHardwareInfo { +enum class MemoryPressureLevel : uint8_t { + Normal = 1, + Warning = 2, + Critical = 4, +}; + +MemoryPressureLevel memoryPressureLevel(); +QString memoryPressureLevelName(); +} // namespace MacOSHardwareInfo +#endif \ No newline at end of file diff --git a/launcher/minecraft/launch/EnsureAvailableMemory.cpp b/launcher/minecraft/launch/EnsureAvailableMemory.cpp index cb7a04ab1..941aee2d0 100644 --- a/launcher/minecraft/launch/EnsureAvailableMemory.cpp +++ b/launcher/minecraft/launch/EnsureAvailableMemory.cpp @@ -25,6 +25,47 @@ EnsureAvailableMemory::EnsureAvailableMemory(LaunchTask* parent, MinecraftInstan void EnsureAvailableMemory::executeTask() { +#ifdef Q_OS_MACOS + QString text; + switch (MacOSHardwareInfo::memoryPressureLevel()) { + case MacOSHardwareInfo::MemoryPressureLevel::Normal: + emitSucceeded(); + return; + case MacOSHardwareInfo::MemoryPressureLevel::Warning: + text = + tr("The system is under increased memory pressure. This may cause lag or slowdowns.\n" + "If possible, close other applications before continuing.\n\n" + "Launch anyway?"); + break; + case MacOSHardwareInfo::MemoryPressureLevel::Critical: + text = + tr("Your system is under critical memory pressure. This may lead to severe slowdowns or crashes.\n" + "It is highly recommended to close other applications or restart your system.\n\n" + "Launch anyway?"); + break; + } + + bool shouldAbort = false; + + if (m_instance->settings()->get("LowMemWarning").toBool()) { + auto* dialog = CustomMessageBox::selectable(nullptr, tr("High memory pressure"), text, QMessageBox::Icon::Warning, + QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, + QMessageBox::StandardButton::No); + + shouldAbort = dialog->exec() == QMessageBox::No; + dialog->deleteLater(); + } + + const auto message = tr("The system is under high memory pressure"); + if (shouldAbort) { + emit logLine(message, MessageLevel::Fatal); + emitFailed(message); + return; + } + + emit logLine(message, MessageLevel::Warning); + emitSucceeded(); +#else const uint64_t available = HardwareInfo::availableRamMiB(); if (available == 0) { // could not read @@ -66,4 +107,5 @@ void EnsureAvailableMemory::executeTask() } emitSucceeded(); +#endif } diff --git a/launcher/minecraft/launch/PrintInstanceInfo.cpp b/launcher/minecraft/launch/PrintInstanceInfo.cpp index 7bfe73746..df8c28c7b 100644 --- a/launcher/minecraft/launch/PrintInstanceInfo.cpp +++ b/launcher/minecraft/launch/PrintInstanceInfo.cpp @@ -68,7 +68,12 @@ void PrintInstanceInfo::executeTask() ::runPciconf(log); #else log << "CPU: " + HardwareInfo::cpuInfo(); +#ifdef Q_OS_MACOS + log << "Memory pressure level: " + MacOSHardwareInfo::memoryPressureLevelName(); +#else log << QString("RAM: %1 MiB (available: %2 MiB)").arg(HardwareInfo::totalRamMiB()).arg(HardwareInfo::availableRamMiB()); +#endif + #endif log.append(HardwareInfo::gpuInfo()); log << ""; From 5d9622db214850104d16a7d1004617eb7054a24c Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Tue, 14 Apr 2026 23:02:44 +0500 Subject: [PATCH 4/4] Use newlines more often in macOS dialog for a nicer look Signed-off-by: Octol1ttle --- launcher/minecraft/launch/EnsureAvailableMemory.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/launcher/minecraft/launch/EnsureAvailableMemory.cpp b/launcher/minecraft/launch/EnsureAvailableMemory.cpp index 941aee2d0..0f349674a 100644 --- a/launcher/minecraft/launch/EnsureAvailableMemory.cpp +++ b/launcher/minecraft/launch/EnsureAvailableMemory.cpp @@ -33,14 +33,16 @@ void EnsureAvailableMemory::executeTask() return; case MacOSHardwareInfo::MemoryPressureLevel::Warning: text = - tr("The system is under increased memory pressure. This may cause lag or slowdowns.\n" + tr("The system is under increased memory pressure.\n" + "This may lead to lag or slowdowns.\n" "If possible, close other applications before continuing.\n\n" "Launch anyway?"); break; case MacOSHardwareInfo::MemoryPressureLevel::Critical: text = - tr("Your system is under critical memory pressure. This may lead to severe slowdowns or crashes.\n" - "It is highly recommended to close other applications or restart your system.\n\n" + tr("Your system is under critical memory pressure.\n" + "This may lead to severe slowdowns, crashes or system instability.\n" + "It is recommended to close other applications or restart your system.\n\n" "Launch anyway?"); break; }