Fortunately there is a way to solve this problem. We have to run the problem program inside a wrapper which assigns it a maximum amount of memory. The wrapper uses windows Job Objects to limit the amount of memory any given job or program can use. Here's my source code in C++:
I compiled this with Visual C++ Express Edition with no problems. If you need this feel free to use it. It could be written so that the name of the program and the memory limits are not hard coded, but I was just seeking a quick fix and I don't anticipate using this for any other applications at this point. Eventually I might write a command line intepreter for it so you can specify the target application and maximum memory, etc.
// maxmem.cpp : Defines the entry point for the application.
//
#include
#include
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
SIZE_T MaxMemory = 7864320000;
HANDLE job = CreateJobObject(0,"ComsolWrapper");
if (job == NULL) {
MessageBox(NULL,"Unable to create job object.",
"CreateJobObject Error",
MB_OK|MB_ICONEXCLAMATION);
return 1;
}
STARTUPINFO startupinfo;
PROCESS_INFORMATION processinformation;
memset(&startupinfo,0,sizeof(STARTUPINFO));
memset(&processinformation,0,sizeof(PROCESS_INFORMATION));
if (0 == CreateProcess("c:\\COMSOL35a\\bin\\comsol64.exe",0,0,0,false,
CREATE_SUSPENDED,0,0,
&startupinfo,&processinformation)) {
MessageBox(NULL,"Unable to open Comsol.",
"CreateProcess Error",MB_OK|MB_ICONEXCLAMATION);
return 1;
}
if (0 == AssignProcessToJobObject(job,processinformation.hProcess)) {
char *buffer = new char[256];
sprintf_s(buffer,256,
"Unable to assign Comsol process to Job Object, Error %d",
GetLastError());
MessageBox(NULL,buffer,"AssignProcessToJobObject Error",
MB_OK|MB_ICONEXCLAMATION);
}
JOBOBJECT_EXTENDED_LIMIT_INFORMATION joeli;
joeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_JOB_MEMORY;
joeli.BasicLimitInformation.MinimumWorkingSetSize = 0;
joeli.BasicLimitInformation.MaximumWorkingSetSize = 0;
joeli.BasicLimitInformation.ActiveProcessLimit = 0;
joeli.BasicLimitInformation.Affinity = 0;
joeli.BasicLimitInformation.PriorityClass = 0;
joeli.BasicLimitInformation.SchedulingClass = 0;
joeli.ProcessMemoryLimit = 0;
joeli.JobMemoryLimit = MaxMemory;
joeli.PeakJobMemoryUsed = 0;
joeli.PeakProcessMemoryUsed = 0;
if (0 == SetInformationJobObject(job,
JobObjectExtendedLimitInformation,
&joeli,
sizeof(joeli))) {
MessageBox(NULL,"Unable to set job object information.",
"SetInformationJobObject Error",
MB_OK|MB_ICONEXCLAMATION);
}
ResumeThread(processinformation.hThread);
WaitForSingleObject(processinformation.hProcess,INFINITE);
return 0;
}