Windows Server 2008(sp1)上运行的Delphi应用程序是否没有回收内存? [英] Is the memory not reclaimed for Delphi apps running on Windows Server 2008 (sp1)?

查看:89
本文介绍了Windows Server 2008(sp1)上运行的Delphi应用程序是否没有回收内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个D2007应用程序,当在Windows Server 2008(x64,sp1)上运行时,其内存占用量稳定增长.
它在Windows Server 2003(x32或x64),XP等上正常运行,并且按预期方式会上升和下降.
我们尝试使用随附的Memory Manager或最新的FastMM4 4.92,但结果相同.

We have a D2007 application whose memory footprint grows steadily when running on Windows Server 2008 (x64, sp1).
It behaves normally on Windows Server 2003 (x32 or x64), XP, etc... where it goes up and down as expected.
We have tried with the included Memory Manager or the latest FastMM4 4.92 with the same results.

有没有人试图监视Win2008上任何Delphi应用程序的内存使用情况并确认?
还是有什么线索?

Has anyone tried to monitor the memory usage of any Delphi app on Win2008 and would confirm?
Or would have any clue?

注意事项:
-没有常识性的内存泄漏(是的,我对FastMM等非常熟悉)
-使用Process Explorer监视内存使用情况; Win2008上虚拟内存(私人字节)和物理内存(WorkingSet Private)都在增长.
-即使存在内存压力,内存消耗仍在增长. (这就是我们来调查的原因,因为它导致了失败,但仅限于Win2008机器上)

Precisions:
- no memory leaks in the common sense (and yes I'm quite familiar with FastMM et al)
- memory usage was monitored with Process Explorer; both Virtual Memory (Private Bytes) and Physical Memory (WorkingSet Private) are growing on Win2008
- memory consumption was still growing even when there was memory pressure. (that's how we came to investigate as it caused a failure, but only on Win2008 boxes)

更新://** **//代码比我们的应用程序简单得多,但表现出相同的行为.
创建一个包含10,000,000个对象的列表,然后创建10,000,000个接口,执行2次将使使用的内存增加大约60MB,对于Windows Server 2008上的100次执行,使用的内存大约增加300MB,但仅返回到XP的位置.
如果启动多个实例,则不会释放内存以允许其他实例运行.相反,页面文件会增长,服务器会爬行...

Update: the //** repaced **// code is much simpler than our app but shows the same behavior.
Creating a List of 10,000,000 objects then 10,000,000 interfaces, executed 2 times grows the used memory by ~60MB and roughly 300MB more for 100 more executions on Windows Server 2008, but just returns to where it was on XP.
If you launch multiple instances, the memory is not released to allow the other instances to run. Instead, the page file grows and the server crawls...

更新2 :请参见质量控制报告73347
经过进一步调查,我们已将其跟踪到关键部分,如下面的代码所示.
使用Button将代码放入简单的VCL应用程序中.并使用Process Explorer进行监视:
它开始时为〜2.6 MB,运行5次(单击按钮)后保持为〜118.6MB.
在5次执行中丢失了116MB.

Update 2: see QC report 73347
After further investigation, we have tracked it down to Critical Sections as shown in the code below.
Put that code into a simple VCL application with a Button. And monitor with Process Explorer:
it starts at ~2.6 MB and after 5 runs (clicks on the button) it stays at ~118.6MB.
116MB lost in 5 executions.

//***********************
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;

推荐答案

实际上,Microsoft对关键部分进行了更改,以添加一些调试信息.该调试内存在应用程序结束之前不会释放,而是以某种方式缓存和重用,这就是为什么它一段时间后会达到稳定状态的原因.

Actually, Microsoft made a change to the Critical Sections to add some debug information. This debug memory is not released until the end of the application but somehow cached and reused which is why after a while it can plateau.

如果要创建许多关键部分而又不感到内存损失的解决方案是修补VCL代码,以通过调用 InitializeCriticalSectionEx <来代替对 InitializeCriticalSection 的调用. /strong>,并向其传递 CRITICAL_SECTION_NO_DEBUG_INFO 标志,以避免创建调试结构.

The solution if you want to create a lot of Critical Sections without feeling this memory penalty is to patch the VCL code to replace calls to InitializeCriticalSection by calls to InitializeCriticalSectionEx and pass it the flag CRITICAL_SECTION_NO_DEBUG_INFO to avoid the creation of the debug structure.

这篇关于Windows Server 2008(sp1)上运行的Delphi应用程序是否没有回收内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆