At first I couldn’t believe that such tool wasn’t readily available because I’ve seen dozens of posts on different forums asking how to do this, however… I guess nobody felt urged enough to actually write a command line app for this. Well, I did 😉 startwithmemlimit is a Win32 application, which can impose a hard limit on the maximum amount of virtual memory a process (and *by default* its children) can allocate. It uses Windows Jobs mechanism, available since Windows 2000. You can read a lot about it on Google and on MSDN, e.g. here, here and here. I prepared the binaries with 32- and 64-bit compilers provided with Windows SDK. You can also recompile them yourself if you’d like 😉 The code is BSD-licensed as always.


startwithmemlimit32.exe command_line mem_limit_in_MB
startwithmemlimit64.exe command_line mem_limit_in_MB


Source code (BSD-licensed):

#define _WIN32_WINNT 0x05000
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

class ScopedHandle {
    ScopedHandle(): m_Handle(NULL) {}
    ScopedHandle(HANDLE h): m_Handle(h) {}
    ~ScopedHandle() { if (m_Handle != NULL) CloseHandle(m_Handle); }
    ScopedHandle& operator=(HANDLE h) { m_Handle = h; return *this; }
    bool operator==(HANDLE h) const { return (m_Handle == h); }
    operator HANDLE() const { return m_Handle; }
    HANDLE m_Handle;

int main(int argc, char *argv[])
    if (argc != 3) {
        printf("Usage: startwithlimit command_line memory_limit_MBn");
        return -1;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    if (!CreateProcess(NULL, argv[1], NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
        printf("Failed to create processn");
        return -2;
    ScopedHandle hProcess = pi.hProcess;
    ScopedHandle hThread = pi.hThread;
    ScopedHandle hJob = CreateJobObject(NULL, NULL);
    if (hJob == NULL) {
        printf("Failed to create jobn");
        return -3;
    if (!QueryInformationJobObject(hJob, JobObjectExtendedLimitInformation, &eli, sizeof(eli), NULL)) {
        printf("Failed to query job infon");
        return -4;
    eli.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_JOB_MEMORY;
    eli.JobMemoryLimit = _atoi64(argv[2]) * 1024 * 1024;
    if (!SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &eli, sizeof(eli))) {
        printf("Failed to set job infon");
        return -5;
    if (!AssignProcessToJobObject(hJob, hProcess)) {
        printf("Failed to assign process to jobn");
        return -6;
    if (ResumeThread(hThread) == -1) {
        printf("Failed to resume processn");
        return -7;
    return 0;

Leave a Reply

Your email address will not be published. Required fields are marked *