Skip to content

Instantly share code, notes, and snippets.

Last active November 23, 2023 21:16
  • Star 18 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
FreeStandbyMemory.bat - ninja edits at
/* 2>nul || title FreeStandbyMemory.bat by AveYo v2019.06.01
@echo off|| csc compiling snippet, advanced schedule, builtin add_remove - UPDATE: reliable free memory detection
:: check_admin_rights
reg query "HKEY_USERS\S-1-5-20\Environment" /v TEMP >nul 2>nul || (
color 0e & echo. & echo PERMISSION DENIED! Right-click %~nx0 ^& Run as administrator
timeout /t -1 & color 0f & title %COMSPEC% & exit/b
:: add_remove whenever script is run again
schtasks /query /tn FreeStandbyMemory >nul 2>nul && (
schtasks /Delete /TN "FreeStandbyMemory" /f 2>nul
reg delete HKLM\Software\AveYo /v FreeStandbyMemory /f 2>nul
del /f /q "%Windir%\FreeStandbyMemory.exe" 2>nul
color 0b &echo. &echo REMOVED! Run script again to recompile and add schedule!
timeout /t -1 &color 0f &title %COMSPEC% &exit/b
:: compile c# snippet
pushd %~dp0
del /f /q FreeStandbyMemory.exe >nul 2>nul
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%Windir%\Microsoft.NET\*csc.exe"') do set "csc="%%v""
%csc% /out:FreeStandbyMemory.exe /target:winexe /platform:anycpu /optimize /nologo "%~f0"
if not exist FreeStandbyMemory.exe echo ERROR! Failed compiling c# snippet & timeout /t -1 & exit /b
echo|set/p=FreeStandbyMemory.exe &copy /y FreeStandbyMemory.exe "%Windir%\FreeStandbyMemory.exe" &set "OUTDIR=%Windir%"
if not exist "%Windir%\FreeStandbyMemory.exe" echo WARNING! Cannot copy FreeStandbyMemory.exe to %Windir%\ &set "OUTDIR=%CD%"
:: setup advanced schedule - can afford higher priority after switching from wmi to winapi
set "task_run=%OUTDIR%\FreeStandbyMemory.exe %CLEAR_WHEN_UNDER_MB% %CLEAR_SYSTEMCACHEWS%"
set "schedule=/Create /RU "System" /NP /RL HIGHEST /F /SD "01/01/2001" /ST "01:00:00" "
schtasks %schedule% /SC MINUTE /MO %CLEAR_EVERY_MINUTES% /TN "FreeStandbyMemory" /TR "%task_run%"
set "sset=$s=New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Priority 1 -StartWhenAvailable;"
set "stopexisting=$s.CimInstanceProperties['MultipleInstances'].Value=3;"
powershell -noprofile -c "%sset% %stopexisting% $null=Set-ScheduledTask -TaskName FreeStandbyMemory -Settings $s"
:: trigger task, force a manual clear and finish setup
schtasks /Run /TN "FreeStandbyMemory"
echo Clearing StandbyMemory every %CLEAR_EVERY_MINUTES% minutes ONLY if free memory goes under %CLEAR_WHEN_UNDER_MB% MB
echo Can force a clear manually from Command Prompt (Admin) by entering: freestandbymemory
echo ADDED! Run "%~nx0" again to remove compiled snippet and schedule!
timeout /t -1
exit /b
:: Based on idea from "PowerShell wrapper script for clear StandBy memory without RAMMap" by Alexander Korotkov
:: Implemented SetSystemFileCacheSize and NtSetSystemInformation suggestions by Maks.K
:: Using RtlAdjustPrivilege, GetPerformanceInfo, force clear if no args, stripped output, sanitized by AveYo
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Reflection;
namespace FreeStandbyMemory
class Program
static bool retv = false;
static int MemoryPurgeStandbyList = 0x0004;
const int SystemFileCacheInformation = 0x0015;
const int SystemMemoryListInformation = 0x0050;
const int SE_INCREASE_QUOTA_PRIVILEGE = 0x00000005;
const int SE_PROF_SINGLE_PROCESS_PRIVILEGE = 0x0000000d;
private class PERFINFO
public int cb;
public IntPtr CommitTotal;
public IntPtr CommitLimit;
public IntPtr CommitPeak;
public IntPtr PhysicalTotal;
public IntPtr PhysicalAvailable;
public IntPtr SystemCache;
public IntPtr KernelTotal;
public IntPtr KernelPaged;
public IntPtr KernelNonpaged;
public IntPtr PageSize;
public int HandleCount;
public int ProcessCount;
public int ThreadCount;
public PERFINFO()
this.cb = (int)Marshal.SizeOf(typeof(PERFINFO));
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport( "psapi.dll", CharSet = CharSet.Auto, SetLastError = true )]
static extern bool GetPerformanceInfo([In, Out] PERFINFO pi);
static extern bool EmptyWorkingSet(IntPtr hwProc);
static extern bool SetSystemFileCacheSize(IntPtr MinimumFileCacheSize, IntPtr MaximumFileCacheSize, int Flags);
static extern IntPtr RtlAdjustPrivilege(int Privilege, bool Enable, bool CurrentThread, out bool RetValue);
static extern IntPtr NtSetSystemInformation(int InfoClass, out int Info, int Length);
static void Main(string[] args)
int target = (args.Length == 0) ? Int32.MaxValue : Convert.ToInt32(args[0]);
bool systemcachews = (args.Length == 0 || args.Length >= 2 && args[1] == "1");
Int64 free = 0;
if (GetPerformanceInfo(pi))
Int64 avail = pi.PhysicalAvailable.ToInt64();
Int64 cache = pi.SystemCache.ToInt64();
Int64 page = pi.PageSize.ToInt64();
free = ( (avail > cache) ? avail - cache : cache - avail ) * page >> 20;
/* To debug, change csc /target:winexe to /target:exe and uncomment the Console.WriteLine's */
////Console.WriteLine("Total: {0,5}MB", pi.PhysicalTotal.ToInt64() * page >> 20);
////Console.WriteLine("Avail: {0,5}MB", pi.PhysicalAvailable.ToInt64() * page >> 20);
////Console.WriteLine("Cache: {0,5}MB", pi.SystemCache.ToInt64() * page >> 20);
////Console.WriteLine("Free: {0,5}MB", free);
if (free > target) return;
////Console.WriteLine("Target:{0,5}MB - CLEARING!", target);
RtlAdjustPrivilege(SE_INCREASE_QUOTA_PRIVILEGE, true, false, out retv);
RtlAdjustPrivilege(SE_PROF_SINGLE_PROCESS_PRIVILEGE, true, false, out retv);
NtSetSystemInformation(SystemMemoryListInformation, out MemoryPurgeStandbyList, Marshal.SizeOf(MemoryPurgeStandbyList));
if (systemcachews) {
SetSystemFileCacheSize(new IntPtr(-1), new IntPtr(-1), 0);
Process[] processlist = Process.GetProcesses(); // Also free system processes working sets:
foreach(Process p in processlist) if (p.SessionId == 0) try { EmptyWorkingSet(p.Handle); } catch (Exception) {}
* text=auto
* eol=crlf
Copy link

Is CLEAR_SYSTEMCACHEWS a boolean value of 0 or 1?

Copy link

AveYo commented Aug 1, 2019

int target = (args.Length == 0) ? Int32.MaxValue : Convert.ToInt32(args[0]);
bool systemcachews = (args.Length == 0 || args.Length >= 2 && args[1] == "1");

Calling without arguments: FreeStandbyMemory.exe
~ assumes you want a forced clear, so it sets target=MaxValue (more than your memory size) and systemcachews=true
Calling with only one argument: FreeStandbyMemory.exe 1024
~ assumes it's the CLEAR_WHEN_UNDER_MB parameter, so it sets target=1024 and systemcachews=false
Calling with two arguments: FreeStandbyMemory.exe 512 1
~ assumes first is the CLEAR_WHEN_UNDER_MB parameter, so it sets target=512
~ assumes second is the CLEAR_SYSTEMCACHEWS parameter, and only if it's "1" (as string) then sets systemcachews=true
otherwise sets systemcachews=false

Copy link

Thank you.

Copy link

Problem: Scheduled tasks Action with added arguments doesn't perform (eg 4096 0).
Note: Scheduled task Action with no added arguments does perform.
Running Windows 10 Pro 1903 18362.267

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment