首页  编辑  

锁定内存块,不允许放到虚拟内存中交换出去

Tags: /超级猛料/OS.操作系统/   Date Created:

如何锁定一个地址空间块在物理内存中,不允许页面交换出去,放到虚拟内存中?

下面是一个简单的例子:

如果不点击 Btn2,那么一旦最小化程序,就会发现程序的物理内存占用大大减小,只有2M左右,其余的内存都被交换(swap)到虚拟内存中去了,这样如果你的程序要继续访问pos_array的话,就会导致Page Fault(可用Process Explorer去查看进程的内存相关的性能参数),即内存页面访问失败,需要从虚拟内存中重新交换到物理内存,从而导致性能降低。

点击Btn2之后,pos_array这72MB的内存就永久锁定在物理内存了,即使最小化也不会被交换出去,可以用Process Explorer看到,不论点击Btn1多少次,Page Fault几乎不增加的。而没有Btn2的话,只要最小化,再次点击Btn1就会导致大量的Page Fault!

var

 pos_array: array[1..30, 1..640*480] of TPoint; // 共约72MB内存!如果不VirtualLock,一旦最小化程序,就会导致内存被交换出去到虚拟内存中。

procedure TForm1.Btn1Click(Sender: TObject);

var

 i : Integer;

 j : Integer;

begin

 for i := 1 to 30 do

   for j := 1 to 640 * 480 do

   begin

     pos_array[i][j].X := Random(640);

     pos_array[i][i].Y := Random(480);

   end;

end;

procedure TForm1.btn2Click(Sender: TObject);

var

 pid : Thandle;

 process: THandle;

begin

 pid := GetCurrentProcessId;

 process := OpenProcess(PROCESS_SET_QUOTA, FALSE, pid);

 if not SetProcessWorkingSetSize(Process, 400*1000*1000, 400*1000*1000) then Beep;

 VirtualLock(@pos_array[1][1], SizeOf(pos_array));

 Caption := SysErrorMessage(GetLastError);

end;