Resetting working memory set on Windows

winapi

I was requested to make a program one day, to reset the memory of a process that was eating and eating memory until the computer crashed. It was a corporate sized program, and it just shows how friggin’ horrible can corporate developers be. Situation was that once you start that program and leave it running, it will slowly consume the memory more and more until your system crashed or it became unbearable. The catch here was that if you would minimize the program, it would reset the memory that it consumed and start to consume again, so to keep your system and that program running, you would have to do it every half hour or something, which is friggin’ ridiculous.
Don’t bother contacting the devs, I had to find a way to reset that memory myself without doing it manually every hour.

It sounds so easy – simply find the window with a program name in it, get a handle for it, minimize and restore, right? WRONG.
It didn’t happen that easily, and at that time I didn’t know it was called a “working application set”. Had to do quite some digging and hair pulling until I stumbled upon a very direct answer to my problems. It said:

When an application’s top-level window is minimized through the Minimize command from its System menu or a click on its Minimize button, the operating system will trim the working set for the process. This is done to free up RAM for foreground applications.

and further down:

If an application minimizes its top-level window programmatically by calling the ShowWindow() API with the SW_MINIMIZE command, the working set of the process will be trimmed. However, the working set will not be trimmed when the window is programmatically minimized through the use of ShowWindow() with the SW_SHOWMINIMIZED command.

Minimizing the program and then restoring it was my last resort, because annoying the user is the last thing I wanna do. So reading further down it said this:

A process can explicitly trim its own working set by calling the SetProcessWorkingSetSize() API while passing “-1” for both the dwMinimumWorkingSetSize and dwMaximumWorkingSetSize parameters. This is essentially how the system trims the process when its top-level window is minimized.

Oh hell yeah! I thought. And so after some fiddling around I was able to make my program “trim the working set” of that shitty corporate program.

Code that I had devised can be found here, also below:

/*
	Author: Kulverstukas
	Website: http://9v.lt; Evilzone.org
	Description:
		Program to reset the working set of a process.
*/
 
#include "windows.h"
#include "stdio.h"
#include <tlhelp32.h>
#include <winbase.h>
 
#define PROCESS_NAME    "memory_hog.exe"
#define RESET_AFTER     900000  // 15 minutes
 
using namespace std;
 
int main() {
    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);
 
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
 
    while (true) {
        if (Process32First(snapshot, &entry) == TRUE) {
            while (Process32Next(snapshot, &entry) == TRUE) {
                if (stricmp(entry.szExeFile, PROCESS_NAME) == 0) { // find the process
                    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
                    SetProcessWorkingSetSize(hProcess, -1, -1); // reset the leak
                    CloseHandle(hProcess);
                }
            }
        }
        CloseHandle(snapshot);
        Sleep(RESET_AFTER);
    }
 
    return 0;
}
guest

0 Comments
Inline Feedbacks
View all comments