我们有一个 D2007 应用程序,它在 Windows Server 2008(x64,sp1)上运行时内存占用量稳定增长。
它在 Windows Server 2003(x32 或 x64)、XP 等上正常运行......它按预期上升和下降。
我们已经尝试使用包含的内存管理器或最新的 FastMM4 4.92,结果相同。
有没有人试图在 Win2008 上监控任何 Delphi 应用程序的内存使用情况并确认?
或者会有什么线索?
精度:
- 没有一般意义上的内存泄漏(是的,我对 FastMM 等人非常熟悉)
- 使用 Process Explorer 监控内存使用情况;虚拟内存(私有字节)和物理内存(WorkingSet Private)在 Win2008 上都在增长
- 即使存在内存压力,内存消耗仍在增长。(这就是我们来调查的原因,因为它导致了失败,但仅限于 Win2008 机器)
更新: //** repaced **// 代码比我们的应用程序简单得多,但表现出相同的行为。
创建一个包含 10,000,000 个对象和 10,000,000 个接口的列表,执行 2 次后,在 Windows Server 2008 上执行 100 次后,使用的内存将增加约 60MB 和大约 300MB,但只是返回到它在 XP 上的位置。
如果您启动多个实例,则不会释放内存以允许其他实例运行。相反,页面文件增长并且服务器爬网......
更新 2:见QC 报告 73347
经过进一步调查,我们已将其追踪到关键部分,如下面的代码所示。
将该代码放入带有 Button 的简单 VCL 应用程序中。并使用 Process Explorer 进行监控:
它从 ~2.6 MB 开始,运行 5 次后(单击按钮)保持在 ~118.6MB。
在 5 次执行中丢失了 116MB。
//***********************
const
CS_NUMBER = 10000000;
type
TCSArray = Array[1..CS_NUMBER] of TRTLCriticalSection;
PCSArray = ^TCSArray;
procedure TestStatic;
var
csArray: PCSArray;
idx: Integer;
begin
New(csArray);
for idx := 1 to length(csArray^) do
InitializeCriticalSection(csArray^[idx]);
for idx := 1 to length(csArray^) do
DeleteCriticalSection(csArray^[idx]);
Dispose(csArray);
end;
procedure TestDynamic(const Number: Integer);
var
csArray: array of TRTLCriticalSection;
idx: Integer;
begin
SetLength(csArray, Number);
for idx := Low(csArray) to High(csArray) do
InitializeCriticalSection(csArray[idx]);
for idx := Low(csArray) to High(csArray) do
DeleteCriticalSection(csArray[idx]);
end;
procedure TForm4.Button1Click(Sender: TObject);
begin
ReportMemoryLeaksOnShutdown := True;
TestStatic;
TestDynamic(CS_NUMBER);
end;