如何限制应用程序可以分配的内存

我需要一种方法来限制服务可能分配的内存量,以防止服务饿死系统,类似于SQL Server允许您设置“最大服务器内存”的方式。

我知道SetProcessWorkingSetSize并不完全符合我的要求,但是我试图让它以我相信它应该的方式行事。 无论我使用的是什么值,我的testing应用程序的工作集不受限制。 此外,如果之后立即调用GetProcessWorkingSetSize,则返回的值不是我之前指定的值。 这里是我的testing应用程序使用的代码:

var MinWorkingSet: SIZE_T; MaxWorkingSet: SIZE_T; begin if not SetProcessWorkingSetSize(GetCurrentProcess(), 20, 12800 ) then RaiseLastOSError(); if GetProcessWorkingSetSize(GetCurrentProcess(), MinWorkingSet, MaxWorkingSet) then ShowMessage(Format('%d'#13#10'%d', [MinWorkingSet, MaxWorkingSet])); 

没有错误发生,但GetProcessWorkingSetSize返回的最小值和最大值都是81,920。

我试着在Flags参数中使用SetProcessWorkingSetSizeEx使用QUOTA_LIMITS_HARDWS_MAX_ENABLE($ 00000004)。 不幸的是,SetProcessWorkingSetSizeEx失败,代码87.参数不正确“,如果我在标志中传递除$ 00000000以外的任何东西。

我也追求使用Job Objects来实现相同的目标。 当启动subprocess时,我有内存限制使用作业对象。 但是,我需要一种服务来设置自己的内存限制,而不是依赖于“启动”服务。 到目前为止,我还没有find一种方法让单个进程创build一个作业对象,然后将其自身添加到作业对象中。 访问被拒绝时,这总是失败。

任何想法或build议?

SetProcessWorkingSetSize函数的文档说:

dwMinimumWorkingSetSize [in]

该参数必须大于零但小于或等于最大工作集大小。 默认大小是50页(例如,在具有4K页面大小的系统上,这是204,800字节)。 如果该值大于零但小于20页,则最小值设置为20页。

在4K页面大小的情况下,强加的最小值是20 * 4096 = 81920字节,这是您看到的值。 这些值以字节为单位指定。

为了实际限制服务进程的内存,我认为可以创建一个新的工作( CreateJobObject ),设置内存限制( SetInformationJobObject ),并将当前进程分配给服务启动例程中的作业( AssignProcessToJobObject )。

不幸的是,在Windows 8和server 2012之前的Windows中,如果进程已经属于某个作业,这将不起作用:

Windows 7,Windows server 2008 R2,带有SP3,Windows server 2008,Windows Vista和Windows server 2003的Windows XP:该流程不得已分配给作业; 如果是,则该函数将以ERROR_ACCESS_DENIED失败。 此行为从Windows 8和Windows server 2012开始更改。

如果是这种情况(例如,在较旧的Windows上得到ERROR_ACCESS_DENIED ),请检查进程是否已分配给作业(在这种情况下,您运气不佳),但也要确保它具有所需的访问权限: PROCESS_SET_QUOTAPROCESS_TERMINATE