Skip to content

feat: add Standby List Cleaner tab (ISLC-style memory purge) - #1089

Merged
laurentiu021 merged 1 commit into
mainfrom
feat/standby-cleaner
Jun 26, 2026
Merged

laurentiu021 merged 1 commit into
mainfrom
feat/standby-cleaner

Conversation

@laurentiu021

@laurentiu021 laurentiu021 commented Jun 26, 2026 •

Copy link
Copy Markdown
Owner

What

Implements Standby List Cleaner (Gaming & Profiles), replacing its WIP placeholder. Closes #325.

The built-in equivalent of ISLC — frees cached "standby" memory to reduce stutter when RAM runs low in games.

How

  • StandbyMemoryService:
    • Stats via GlobalMemoryStatusEx (total / available / load%) — no admin, so the display is always live.
    • Purge via ntdll NtSetSystemInformation(SystemMemoryListInformation=80, MemoryPurgeStandbyList=4) — the RAMMap/ISLC mechanism.
    • The privilege trap, handled — purging needs SeProfileSingleProcessPrivilege enabled on an elevated token. The service enables it via AdjustTokenPrivileges and then checks GetLastError == ERROR_NOT_ALL_ASSIGNED — because AdjustTokenPrivileges returns true even when the privilege isn't held (a non-elevated token), so a naive check would silently no-op. Without this, the purge appears to "do nothing".
    • All [LibraryImport]; LookupPrivilegeValueW pinned to the W entry point (A/W rule).
  • Safe & non-destructive — the standby list is clean, disk-backed file cache. Clearing it loses no data; Windows reloads from disk on next access. No confirmation dialog needed (nothing to undo), but the UI explains it.
  • StandbyMemoryViewModel — 2s live poll, manual Purge, and an auto-purge toggle + threshold slider (pure ShouldAutoPurge, unit-tested). Purge is gated on AdminHelper.IsElevated() with the standard elevation banner; reading stats works without admin.

Preview

Marked PREVIEW (sidebar pill + banner).

Tests

  • StandbyMemoryTests — ShouldAutoPurge (below/at/above threshold + zero/negative guards), MemoryStatus formatting + MB computation, Empty.
  • Integration: NavLeaf_StandbyCleaner_IsImplementedAndMarkedPreview.

Verification

  • Build main + unit + integration: 0/0. No MessageBox, specific exceptions only.
  • README + ARCHITECTURE updated (counts 47→48 implemented / 10→9 WIP). feat: -> minor 1.42.0.

Implements Standby List Cleaner (replaces its WIP placeholder in Gaming &
Profiles). Closes #325.

- StandbyMemoryService: GlobalMemoryStatusEx for live stats (no admin) and
  ntdll NtSetSystemInformation(SystemMemoryListInformation=80,
  MemoryPurgeStandbyList=4) to purge — the same mechanism RAMMap/ISLC use.
  Enables SeProfileSingleProcessPrivilege via AdjustTokenPrivileges first and
  checks ERROR_NOT_ALL_ASSIGNED (the silent "not admin" trap, since
  AdjustTokenPrivileges returns true even when the privilege isn't held).
  All-[LibraryImport]; LookupPrivilegeValueW pinned to the W entry point.
- Purge is non-destructive: standby is clean disk-backed file cache, so
  clearing it loses nothing (Windows reloads from disk on next use).
- StandbyMemoryViewModel: 2s live poll, manual purge, and threshold-based
  auto-purge (pure ShouldAutoPurge, unit-tested). Reading works without admin;
  purge is gated on AdminHelper.IsElevated() with the standard banner.
- Marked PREVIEW via the badge mechanism.
try
{
Marshal.WriteInt32(buffer, NativeMethods.MemoryPurgeStandbyList);
int status = NativeMethods.NtSetSystemInformation(NativeMethods.SystemMemoryListInformation, buffer, sizeof(int));

private static void EnableProfilePrivilege()
{
if (!NativeMethods.OpenProcessToken(NativeMethods.GetCurrentProcess(),
@laurentiu021
laurentiu021 merged commit 11bbbd3 into main Jun 26, 2026
4 checks passed
@laurentiu021
laurentiu021 deleted the feat/standby-cleaner branch June 26, 2026 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement]: Gaming — Standby List Cleaner (ISLC built-in)

2 participants