私の質問は、悪夢のようなメモリ リークのデバッグに関するものです。
私のアプリには、から派生した単純なクラスがありTObject
ます。そのクラスのすべてのオブジェクトは、から派生したクラスのコレクション/リストに格納されますTObjectList
。
type
TOffer = class(TObject)
Item: string;
Price: string;
Id: string;
end;
TOffers = class(TObjectList<TOffer>)
protected
procedure SetOffer(I: Integer; AOffer: TOffer);
function GetOffer(I: Integer): TOffer;
public
property Offers[I: Integer]: TOffer read GetOffer write SetOffer
end;
使用シナリオ:
クローラーはオファーをダウンロードして解析し、オブジェクト コレクションに保存します。このアプローチは、後でオブジェクトを参照できるため、非常に便利なようです (グリッド/リストを埋める、ファイルに書き込むなど)。
問題は、メモリ リークを回避するためのオブジェクトの適切な破棄です。アプリは開始時に最大 4Mb のメモリを割り当てますが、最大 12k のオファーを処理した後、32Mb を消費します。プロセスが終了した後、適切に破棄されていないオブジェクト/変数によって引き起こされるリーク。
ReportMemoryLeaksOnShutdown
恐ろしい数字を示していますが、重要なのは-どこを見ればいいのか、どうすれば適切にデバッグできるのかわかりません。
別の例はvar MyString: string
、適切な処分が必要な変数です!! それは私にとってちょっとした洞察でした:)各プロシージャ/関数は、スコープ外の変数のガベージコレクションを自動的に管理すると思いました。
オファーのリストは、次の関数によって作成されます。
function GetOffersList: TOffers;
begin
Result := TOffers.Create;
while not rs.EOF do
begin
Offer := TOffer.Create;
try
// here come collected offer attributes as variables of type string:
Order.Item := CollectedOfferItem;
Order.Price := CollectedOfferPrice;
Order.Id := CollectedOfferId;
Result.Add(Offer);
finally
Offer := nil;
end;
end;
end;
次に、これらのオファーをコレクションとして直接扱います。重要なことは、このアプリを 24 時間年中無休で実行することです。そのため、適切なリソースの処分が必須です。
- 上記のタイプのオブジェクトを適切に処分する方法は?
- オブジェクト/オブジェクト リストを管理するための他の手法を検討しますか?
- タイプの変数を適切に破棄する方法は
string
? - Delphi でのメモリ リークとの戦いに関する良い読み物を教えてください。
ありがとうございました。