在我的一個應用程式的任務管理器中注意到奇怪的記憶體行為后,我開始使用 FastMM4 調查記憶體泄漏。剛打開三個表格,我就發現了1000多個。我希望我能在一個地方找到原因
在一種情況下,即使總是釋放 finally 塊中的 TStringList(總是到達),FastMM4 也會報告記憶體泄漏:
function GetMatchingResourceFileName(MatchingString:string) : string;
var
ResourcesList: TStringList;
I : Integer;
begin
Result := '';
try
ResourcesList := TStringList.Create;
// get resource files list
ResourcesList := GetResourceList;
//search for matching file name
for I := 0 to ResourcesList.Count-1 do
begin
if Pos(MatchingString,ResourcesList.Strings[I]) > 0 then
begin
Result := ResourcesList.Strings[I];
break;
end;
end;
finally
ResourcesList.Free;
ResourcesList:= nil;
end;
end;
FastMM4 堆疊報告告訴我泄漏開始于
ResourcesList := TStringList.Create;
即使我 100% 確定ResourcesList.Free;
已執行,我也會看到記憶體泄漏。
在這里可以看到斷點被命中:
當我關閉應用程式時,我看到了報告:
---------------------------
myProject.exe: Memory Leak Detected
---------------------------
This application has leaked memory. The small-block leaks are (excluding expected leaks registered by pointer):
85 - 100 bytes: System.Classes.TStringList x 1
Note: Memory leak detail is logged to a text file in the same folder as this application. To disable this memory leak check, undefine "EnableMemoryLeakReporting".
為了研究上面的泄漏,我評論了我 99% 的代碼集中在第一個報告的泄漏上,實際上是在應用程式的初始化部分。
這怎么可能?
更新
代碼的作業版本避免呼叫TStringList.Create
,因為該GetResourceList
方法已經回傳一個正確創建TStringList
的,以下代碼現在沒有泄漏:
function GetMatchingResourceFileName(MatchingString:string) : string;
var
ResourcesList: TStringList;
I : Integer;
begin
Result := '';
try
ResourcesList := GetResourceList;
//search for matching file name
for I := 0 to ResourcesList.Count-1 do
[...]
uj5u.com熱心網友回復:
你有兩個問題:
1
1. ResourcesList := TStringList.Create;
2. // get resource files list
3. ResourcesList := GetResourceList;
在第 1 行,您創建一個新TStringList
物件并將地址保存到本地ResourcesList
變數中。
但是在第 3 行,我想該GetResourceList
函式還創建了一個新TStringList
物件,然后您重寫了區域ResourcesList
變數,使其指向這個新物件。
這意味著現在沒有變數指向TStringList
您創建的第一個物件。因此,它永遠被泄露。
你想要的是這樣的:
// get resource files list
ResourcesList := GetResourceList;
2
你的代碼本質上是
try
ResourcesList := TStringList.Create; //or GetResourceList;
// Use the list
finally
ResourcesList.Free
end;
這是一個非常常見的錯誤。如果TStringList.Create
建構式(或GetResourceList
函式)失敗,部分創建的TStringList
物件會自動釋放(或希望被GetResourceList
函式釋放),但隨后例外會停止執行,因此不會向ResourcesList
.
因此,ResourcesList.Free
將在隨機指標上運行解構式,因為未初始化非托管型別的區域變數。
你必須做
ResourcesList := TStringList.Create; //or GetResourceList;
try
// Use the list
finally
ResourcesList.Free
end;
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/433782.html
標籤:德尔福 内存泄漏 德尔福-2010 字符串列表 快速mm
上一篇:當D7exe具有清單檔案時,有時表單運行時(Tbutton、Radio、復選框等)中缺少Common-Controls
下一篇:如何提取域名后綴?