我需要一种方法来限制服务可能分配的内存量,以防止服务饥饿系统,类似于Server允许您设置“最大服务器内存”的方式。
我知道SetProcessWorkingSetSize没有做我想做的事情,但我试图让它按照我所认为的那样行事。无论我使用的值是什么,我的测试应用程序的工作集都是不受限制的。此外,如果之后立即调用GetProcessWorkingSetSize,则返回的值与我以前指定的值不同。下面是我的测试应用程序使用的代码:
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。
我尝试在SetProcessWorkingSetSizeEx参数中使用QUOTA_LIMITS_HARDWS_MAX_ENABLE ($00000004)。不幸的是,如果在SetProcessWorkingSetSizeEx中传递00000000美元以外的任何内容,那么代码87就会失败。参数是不正确的。
我还使用Job来实现同样的目标。在启动子进程时,我有使用作业对象的内存限制。但是,我需要一个服务设置自己的内存限制的能力,而不是依赖于“启动”服务来完成它。到目前为止,我还没有找到一个进程创建作业对象然后将自己添加到作业对象的方法。当访问被拒绝时,这总是失败。
有什么想法或建议吗?
发布于 2017-03-11 08:40:43
SetProcessWorkingSetSize
函数的文档说明:
dwMinimumWorkingSetSize in ..。 此参数必须大于零,但小于或等于最大工作集大小。默认大小为50页(例如,在具有4K页大小的系统上,这是204,800字节)。如果值大于零,但小于20页,则最小值设置为20页。
在4K页面大小的情况下,施加的最小值是20 * 4096 = 81920字节,这是您看到的值。值以字节为单位。
要实际限制服务流程的内存,我认为可以创建一个新作业(CreateJobObject
,设置内存限制(SetInformationJobObject
)并将当前进程分配给作业(服务启动例程中的AssignProcessToJobObject
)。
不幸的是,在8之前的Windows和Server 2012上,如果进程已经属于作业,则此操作将无法工作:
Windows 7、Windows 2008 R2、Windows SP3、Windows 2008、Windows和Windows 2003:进程不能分配给作业;如果是,该函数将在ERROR_ACCESS_DENIED中失败。此行为从Windows 8和Windows 2012开始更改。
如果这是你的案子。检查进程是否已经分配给作业(在这种情况下,您运气不好),但也要确保它具有所需的访问权限:PROCESS_SET_QUOTA
和PROCESS_TERMINATE
。
https://stackoverflow.com/questions/42725282
复制相似问题