相关疑难解决方法(0)

可以清理记忆吗?

我在Win32项目中使用Delphi 5(安装了FastMM),并且最近一直在尝试大幅减少此应用程序中的内存使用量.到目前为止,我已将使用量减少了近一半,但在处理单独的任务时发现了一些问题.当我最小化应用程序时,内存使用量从45兆位缩减到1兆位,这归功于它分页到磁盘.当我恢复并重新开始工作时,内存仅增加到15兆.当我继续工作时,内存使用量再次缓慢上升,最小化和恢复将其恢复到15兆.所以我的想法是,当我的代码告诉系统释放内存时,根据Windows仍然保留它,实际的垃圾收集直到很久以后才开始.

任何人都可以确认/否认这种行为吗?是否有可能以编程方式清理内存?如果我继续使用该程序而不执行此手动刷新,我会在一段时间后出现内存不足错误,并希望消除它.谢谢.

编辑:我在about.com上发现了一篇文章,其中提供了很多内容以及其他内存管理领域的链接和数据.

delphi garbage-collection memory-management

30
推荐指数
3
解决办法
8342
查看次数

为什么我的Delphi程序的内存会继续增长?

我正在使用Delphi 2009,它内置了FastMM4内存管理器.

我的程序读入并处理大型数据集.每当我清除数据集或退出程序时,都会正确释放所有内存.它根本没有内存泄漏.

使用spenwarr答案中给出的CurrentMemoryUsage例程:如何获取Delphi程序使用的内存,我已经显示了FastMM4在处理过程中使用的内存.

似乎正在发生的事情是,在每个进程和发布周期之后,内存的使用正在增长.例如:

在没有数据集的情况下启动程序后使用1,456 KB.

加载大型数据集后使用218,455 KB.

完全清除数据集后,为71,994 KB.如果我在此时退出(或我示例中的任何一点),则不会报告内存泄漏.

再次加载相同的数据集后使用271,905 KB.

完全清除数据集后为125,443 KB.

再次加载相同的数据集后使用325,519 KB.

完全清除数据集后179,059 KB.

再次加载相同的数据集后使用378,752 KB.

在每个加载/清除周期中,我的程序的内存使用量似乎增加了大约53,400 KB.任务管理器确认这确实发生了.

我听说当释放对象时,FastMM4并不总是将所有程序的内存释放回操作系统,以便在需要更多时可以保留一些内存.但这种不断增长使我感到困扰.由于没有报告内存泄漏,我无法确定问题.

有谁知道为什么会这样,如果它是坏的,如果有什么我可以或应该做些什么呢?


谢谢dthorpe和Mason的回答.你让我思考并尝试让我意识到自己错过了什么的事情.因此需要进行详细的调试.

事实证明,我的所有结构在退出时都被正确释放.但是在运行期间每个循环后的内存释放不是.它正在累积内存块,如果我的退出清理不正确,通常会导致泄漏,如果我的退出清理不正确则会在退出时检测到 - 但事实确实如此.

我需要在循环之间清除一些StringLists和其他结构.我仍然不确定我的程序如何正常工作,还有早期周期中的额外数据,但确实如此.我可能会进一步研究.

这个问题已得到解答.谢谢你的帮助.

delphi memory-management fastmm

12
推荐指数
1
解决办法
6156
查看次数

为什么我释放内存后程序的内存使用率没有恢复正常?

考虑下一个示例应用程序

program TestMemory;


{$APPTYPE CONSOLE}

uses
  PsAPI,
  Windows,
  SysUtils;

function GetUsedMemoryFastMem: cardinal;
var
    st: TMemoryManagerState;
    sb: TSmallBlockTypeState;
begin
    GetMemoryManagerState(st);
    result := st.TotalAllocatedMediumBlockSize + st.TotalAllocatedLargeBlockSize;
    for sb in st.SmallBlockTypeStates do
    begin
        result := result + sb.UseableBlockSize * sb.AllocatedBlockCount;
    end;
end;

function GetUsedMemoryWindows: longint;
var
  ProcessMemoryCounters: TProcessMemoryCounters;
begin
  Result:=0;
  ProcessMemoryCounters.cb := SizeOf(TProcessMemoryCounters);
  if GetProcessMemoryInfo(GetCurrentProcess(), @ProcessMemoryCounters, ProcessMemoryCounters.cb) then
   Result:= ProcessMemoryCounters.WorkingSetSize
  else
   RaiseLastOSError;
end;

procedure Test;
const
  Size = 1024*1024;
var
  P : Pointer;
begin
  GetMem(P,Size);

      Writeln('Inside');
      Writeln('FastMem '+FormatFloat('#,', GetUsedMemoryFastMem));
      Writeln('Windows '+FormatFloat('#,', GetUsedMemoryWindows));
      Writeln(''); …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-2007

6
推荐指数
1
解决办法
1351
查看次数

删除IDE创建的表单变量是否安全?

我有一个名为MyForm的表单存储在一个名为Unit UnitMyFrom的单元中.当然Delphi自动添加了这段代码:

TYPE
  TMyForm = class(TForm)
  private
  public
 end;

var MyForm: TMyForm;
Run Code Online (Sandbox Code Playgroud)

但我删除了该单位的var声明.有人说这可能会导致IDE出现问题.这是真的吗?IDE是否需要该变量?


编辑:

MyForm不会自动创建.用户在运行时创建该表单.

forms delphi

6
推荐指数
2
解决办法
405
查看次数

如何说服内存管理器释放未使用的内存

在最近的帖子中(我的程序永远不会释放内存.为什么?)我表明在使用FastMM时,应用程序不会释放大量内存回系统.最近我创建了一个人工测试程序,以确保它不是一个内存的问题,它只出现在FastMM中.

在这个程序中,我创建并销毁一个对象(与前一篇文章中使用的对象相同)500次.

内存要求是("私人工作集"):

没有FastMM
在运行循环之前:1.2MB
运行循环后:2.1MB

使用FastMM(激进的调试模式)
在运行循环之前:2.1MB
运行循环后:25MB

使用FastMM(发布模式)
运行循环之前:1.8MB
运行循环后:3MB

如果我多次运行循环,则内存要求不会增加.这意味着重用未释放的内存,因此这不是内存泄漏(内存泄漏会增加内存占用,每次运行时会有几KB/MB).


我的问题是:

如何在FastMM中禁用此行为?它甚至可能吗?我知道,如果我在没有FastMM或FastMM Release Mode的情况下发布程序,它将"浪费"适量的RAM.但是,根据需要禁用此行为,将帮助我(我们?)识别内存泄漏.实际上在我的第一篇文章中(见链接),很多人都认为我有泄漏.由于这种行为,显然造成了混乱.不,很明显没有泄漏.只是内存管理器拒绝释放大量内存.

它会释放额外的内存吗?什么时候?什么引发了这个?程序员可以触发吗?例如,当我知道我已经完成了RAM密集型任务并且用户可能暂时不使用该程序(最小化它)时,我可以将RAM刷回系统吗?当用户打开我的程序的多个实例时会发生什么?他们不会争夺内存吗?

delphi fastmm

5
推荐指数
3
解决办法
3423
查看次数

何时调用SetProcessWorkingSetSize?(说服内存管理器释放内存)

在之前的帖子中(我的程序永远不会释放内存.为什么?)我表明FastMM可以缓存(读取为自身保持)相当大的内存.如果您的应用程序刚刚在RAM中加载了大量数据集,则在释放数据后,您将看到令人印象深刻的RAM未释放回内存池.

我环顾四周,似乎调用SetProcessWorkingSetSize API函数会将缓存"刷新"到磁盘.但是,我无法决定何时调用此函数.我想在执行RAM密集型操作的按钮上的OnClick事件结束时调用它.但是,有些人说这可能会导致AV.

如果有人成功使用此功能,请告诉我(我们).

非常感谢.


编辑:
1.释放数据集后,程序仍然需要大量的RAM.调用SetProcessWorkingSetSize后,大小返回到几MB.有人争辩说什么都没有被释放.我同意.但是内存占用现在很小,并且在正常使用程序后不会增加(例如,在执行不涉及加载大型数据集的正常操作时).不幸的是,没有办法证明交换到磁盘的内存被装回内存,但我认为不是.2.我已经证明了(我希望)这不是内存泄漏:
我的程序永远不会释放内存.为什么?
如何说服内存管理器释放未使用的内存

delphi

2
推荐指数
2
解决办法
3176
查看次数