使用Delphi7为什么一个简单的列表框会增加内存

使用Delphi7为什么一个简单的列表框会增加内存,delphi,memory,listbox,Delphi,Memory,Listbox,我注意到在Windows 10的任务管理器中,使用简单的listbox.clear然后写入它每次都会增加内存使用量。 乙二醇 end 那么,这正常吗;这有关系吗;应用程序内存“使用”在任何操作系统上都是一个相当模糊的概念 如果应用程序依赖操作系统进行所有内存管理,那么性能将是不可接受的 因此,大多数(如果不是所有的话)应用程序在一定程度上管理自己的内存。对于Delphi应用程序来说,情况确实如此 Delphi应用程序管理自己的堆,从操作系统中分配(相对)大块内存,然后根据需要将其分为更小的“块”

我注意到在Windows 10的任务管理器中,使用简单的listbox.clear然后写入它每次都会增加内存使用量。 乙二醇

end

那么,这正常吗;这有关系吗;应用程序内存“使用”在任何操作系统上都是一个相当模糊的概念

如果应用程序依赖操作系统进行所有内存管理,那么性能将是不可接受的

因此,大多数(如果不是所有的话)应用程序在一定程度上管理自己的内存。对于Delphi应用程序来说,情况确实如此

Delphi应用程序管理自己的堆,从操作系统中分配(相对)大块内存,然后根据需要将其分为更小的“块”供应用程序使用。只有当应用程序用完了预先分配的内存时,它才需要返回请求操作系统提供更多内存

这还意味着,在任何给定的时间,一些分配的内存在应用程序中都没有被积极使用

随着内存使用的改变,应用程序将把多余的内存返回操作系统。Delphi应用程序的工作方式这通常发生在应用程序最小化时,例如。因此,如果您最小化并恢复应用程序,您可能会看到“正在使用”的内存发生显著变化。支持这一点的机制有时用于强制应用程序更积极地返回内存,方法是触发相同的进程以响应应用程序只是处于“空闲”状态,而不是专门最小化

然而,这些技术只是解决任务管理器中观察到的记忆使用感知问题,而不是实际减少实际的记忆使用

底线是,从操作系统的角度来看,应用程序使用的内存可能与实际使用的内存非常不同

在您的例子中,一个简化的视图是,为将项目添加到列表框所需的字符串分配了内存。当您清除列表框时,用于这些字符串的内存不会立即返回到系统,因为这相当昂贵,相反,它只是被标记为不再使用(它将在某个时候返回到系统,只是还没有)

在循环的下一次迭代中,当需要向列表框添加更多字符串时,一个高效的内存管理器(在应用程序中)可能会确定以前使用过的内存(尚未返回到操作系统)现在可以重新使用。当然,识别这一点需要时间,因此简单地使用一些“新鲜”内存可能更有效,即使这意味着要求操作系统提供更多内存

将内存返回到操作系统比请求更多内存更复杂(因此“更昂贵”,即需要更长的时间),因为内存只能分块返回,因此即使您的应用程序内存只有10%在“使用”,也可能是正在使用的10%正好分布在整个内存中,这使得某些人无法使用,或者,甚至可能是任何要返回操作系统的内存。您经常会听到这种情况被称为内存“碎片化”

这就是为什么将内存返回到操作系统比分配新内存成本更高的原因,因为要确定哪些内存可以安全返回,必须要做很多工作

回到您的场景:

经过2次迭代后,您将累积两轮已使用且现在标记为不再使用的内存(在应用程序中)。然而,从操作系统的角度来看,该应用程序仍然在“使用”该内存,因为操作系统不知道应用程序自己对该内存的管理中发生了什么。重复足够多的时间,你可以很容易地积累大量“已分配但当前未使用”的内存

但这通常不是你需要担心的事情——当不再需要内存并且操作方便时,应用程序也会将内存返回操作系统,当操作系统要求或告诉应用程序返回内存时,例如当系统内存紧张时

操作系统直接支持应用程序可能正在“使用”其实际未使用的内存,并且可以在需要时要求释放,这一事实应该告诉您,这并不罕见。事实上,这是意料之中的

然而值得一提的是,Delphi内置的内存管理器是可替换的

Delphi7中的默认内存管理器已经足够了,但是有很多替代方案。其中一些是高度专业化的,但特别是一个通用内存管理器——已被证明是对旧的Delphi内存管理器的重大改进,从Delphi 2006起,它被用作新的默认内存管理器

它仍然可以作为一个开源项目免费使用,您可以轻松地将其合并到自己的应用程序中,即使是在Delphi7(或更旧的版本)中。所涉及的只是添加一个单元作为DPR使用列表中的第一个条目

与Delphi 7中的默认内存管理器相比,FastMM提供了更高的内存碎片恢复能力,从而提高了效率和整体性能。它还提供了额外的调试工具,如内存泄漏检测,以及用于识别其他内存错误的工具,如双自由对象和/或所谓的“悬空”指针(在一定程度上)

您可能会发现,在您的测试用例中使用FastMM可能会对您的用例中感知到的内存使用产生影响,但出于所解释的原因,此测试用例本身并不值得关注,除非它在您的应用程序中出现实际问题。

应用程序内存“使用”在任何操作系统上都是一个相当模糊的概念

如果应用程序依赖操作系统来实现所有内存管理性能
for k:=1 to 10 do  begin
assignfile(f,'T:\Programming\WORK\PROG\crap\searchfolders.fil');
reset(f);
listbox1.clear;
while not eof(f) do
  begin
    readln(f,s);  //there are 5 lines of text in the file
    listbox1.items.add(s);
  end;
closefile(f);
MessageDlg('check memory',mtinformation,[mbok], 0); 
//it will have increased by roughly 0.5Mb