delphi - 如何正确处理字符串数组以防止内存泄漏?

标签 delphi memory-leaks

MadExcept 说我的应用程序在以下代码中泄漏了“字符串”内存:

for i := 0 to TotalSpans-1 do
begin
  if i = 0 then LastPos := 1;
  StartPos := PosEx(SubstrAtBegin, RawHtmlStr, LastPos);
  FinishPos := PosEx(SubstrAtEnd, RawHtmlStr, LastPos);
  Spans[i] := Copy(RawHtmlStr, StartPos, FinishPos - StartPos +
    Length(SubstrAtEnd));
  LastPos := FinishPos + Length(SubstrAtEnd);
end;

其中 Spans 是一个字符串数组
其想法是在长 RawHtmlStr 中查找特定值。为此,我首先找到众所周知的相邻子字符串,然后将它们之间的值复制到动态字符串数组中。

整个事情被序列化以在线程中工作。
在最后一次运行中,我解析了大约 15k 个 RawHtmlStr,并且抛出了 38 个异常(主要是 EIdReadTimeout) > 和 EIdSocketError)。我在上层处理了这些异常(只需移至下一个项目),但它们以某种方式导致了 34 个 UnicodeString 泄漏。

madExcept 指向以下行:

Spans[i] := Copy(RawHtmlStr, StartPos, FinishPos - StartPos +
    Length(SubstrAtEnd));

作为邪恶之源。

目前整段代码没有被 try..finally block 包装,因为我不太明白如何处理字符串数组的处理(我认为,它正在被采取)由德尔福照顾,不是吗?)。

在这种情况下,Finalize(Spans) 会执行垃圾回收吗?

最佳答案

有问题的对象是类型

array of string

这是一个动态数组,其生命周期由引用计数管理。数组成员的生命周期也由引用计数管理。

对于托管对象,您不需要采取任何步骤来处置它们。在某些时候,当对该对象的最终引用离开作用域时,该对象将自动销毁。

因此,如果您泄漏这样一个对象,通常意味着包含该对象的任何内容都不会被销毁。例如,此代码会泄漏字符串数组:

type
  TRec = record
    arr: array of string;
  end;
  PRec = ^TRec;
....
var
  Rec: PRec;
....
New(Rec);
SetLength(Rec.arr, 42);
Rec.arr[0] := 'foo';
// and so on

如果您未能处理 Rec,那么它及其内容就会被泄露。

同样,如果您有一个拥有托管对象的类,并且该类被泄漏,那么该类的所有成员也会被泄漏。

type
  TMyClass = class
    arr: array of string;
  end;
....
var
  Obj: TMyClass;
....
Obj := TMyClass.Create;
SetLength(Obj.arr, 42);
Obj.arr[0] := 'foo';
// and so on

同样,如果您无法销毁 Obj,那么它就会泄漏,它的成员也会泄漏。

除了这种情况之外,我可以想象托管类型泄漏的唯一其他方式是堆损坏覆盖引用计数。

关于delphi - 如何正确处理字符串数组以防止内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23237970/

相关文章:

java - 解决 PermGen 问题的各种选择

c# - UWP - 框架导航似乎会导致非托管内存泄漏

delphi - 在 TObject 的 "Create"构造函数中使用继承

sql-server - 为什么 FireDAC 忽略索引名称?

delphi - 如何在delphi 2010中将中文字符串转换为十六进制并达到与delphi 2007 mbcs相同的结果

delphi - IHTMLDocument2 的可用内存

database - 如何根据内容自动调整/缩放 DBGrid(或其他类似)的列宽?

java - JProfiler Heap Walker - 选择位于特定 Java 包中的 GC Root 持有的对象

android - 如何防止android中上下文相关的内存泄漏

c# - 这个单向绑定(bind)会泄漏内存吗?