SetLength()与GetMem()内存占用为何不同?前者是否更优?
SetLength()与GetMem()的内存占用差异分析
我用Delphi XE8对SetLength()和GetMem()进行了内存占用测试,具体情况如下:
SetLength()测试
测试代码:
procedure TForm1.SpeedButton1Click(Sender: TObject); var a: array of Byte; begin SetLength(a,100*1024*1024); //100Mb ShowMessage('See Task Manager'); SetLength(a,0); end;
测试现象:任务管理器显示Project1.exe的内存占用约为100Mb。
GetMem()测试
测试代码:
procedure TForm1.SpeedButton2Click(Sender: TObject); var p: PByte; begin GetMem(p,100*1024*1024); //100Mb ShowMessage('See Task Manager'); FreeMem(p); end;
测试现象:任务管理器显示Project1.exe的内存占用约为2Mb。
现象原因解析
任务管理器显示的是进程的工作集(Working Set),即当前被加载到物理内存中的部分:
SetLength()操作动态数组时,Delphi会自动初始化数组内存(填充0),这会触发Windows立即分配对应大小的物理内存,因此工作集增长与分配的100MB一致。GetMem()仅分配虚拟内存空间,Windows采用延迟分配策略,只有当程序实际写入该内存区域时,才会分配物理内存。测试中未对分配的内存进行写入操作,因此物理内存占用几乎没有变化。
是否SetLength()比GetMem()更优?
不能直接判定SetLength()更优,两者适用于不同场景:
SetLength()用于动态数组,自带长度管理、边界检查,使用更安全,无需手动释放内存(数组离开作用域时自动释放),适合需要数组结构的业务场景。GetMem()直接操作指针,内存分配更灵活,未写入数据时不占用物理内存,节省物理资源,但需要手动调用FreeMem()释放内存,且无边界检查,容易出现内存越界等问题,适合底层内存操作场景。
内容的提问来源于stack exchange,提问作者Bắc Hổ
相关产品推荐
相关产品推荐

