问题
Is it possible to retrieve the amount of memory that is used by a single component in delphi?
I'm downloading simple strings from the internet and I see that the memory usage is up to a gigabyte at by the end of the downloading process, but when I look at the saved file which contains everything I downloaded the file is only in the kilobyte range, clearly there is something going on with the components, even though I destroy them.
Example:
Edit:
procedure TForm1.OnCreate(Sender: TObject);
var list: TStringList;
begin
list:=TStringList.Create;
list.LoadFromFile('10MB_of_Data.txt');
list.destroy;
end;
How can I know that "list" as a TStringList is using 10 MB worth of space in memory?
Thank you.
回答1:
I think comparing the memory usage before and after is the way to go with this as there is no simple way of seeing what memory was allocated by a block of code after the fact... For example, with the string list above, the class itself will only take up a small amount of memory as it is made up of pointers to other allocations (i.e. the array of strings) and that itself is an array of pointers to to the actual strings... and this is a comparatively simple case.
Anyway, this can be done with FastMM with a function like follows...
uses
FastMM4;
function CheckAllocationBy(const AProc: TProc): NativeUInt;
var
lOriginalAllocated: NativeUInt;
lFinalAllocated: NativeUInt;
lUsage: TMemoryManagerUsageSummary;
begin
GetMemoryManagerUsageSummary(lUsage);
lOriginalAllocated := lUsage.AllocatedBytes;
try
AProc;
finally
GetMemoryManagerUsageSummary(lUsage);
lFinalAllocated := lUsage.AllocatedBytes;
end;
Result := lFinalAllocated - lOriginalAllocated;
end;
And can be used like so...
lAllocatedBytes := CheckAllocationBy(
procedure
begin
list:=TStringList.Create;
list.LoadFromFile('10MB_of_Data.txt');
list.Free;
end);
This will tell you how much your string list left behind (which interestingly I get 40 bytes for on the first run of repeated calls and 0 after which after consulting the usage logs before and after the call is two encoding classes created on the first call). If you want to check where leaked memory was allocated, it's simple to use FastMM to do that also (although I agree with the above that if it's 3rd party, it shouldn't be your problem).
回答2:
First of all: please, be patient, this is actually not exactly answer for your question, but it is too large for posting it in comment. This code was written and compiled using FPC, but it can give some estimations for you. May be somebody knows how to port it to the Delphi.
program project4;
uses
SysUtils,
Classes;
var
p: Pointer;
sl: TStringList;
var
a: TFPCHeapStatus;
begin
a := GetFPCHeapStatus;
writeln('== 1 ==');
//writeln(a.MaxHeapSize);
writeln(a.MaxHeapUsed);
//writeln(a.CurrHeapSize);
writeln(a.CurrHeapUsed);
//writeln(a.CurrHeapFree);
GetMem(p, 1024);
a := GetFPCHeapStatus;
writeln('== 2 ==');
writeln(a.MaxHeapUsed);
writeln(a.CurrHeapUsed);
sl := TStringList.Create;
a := GetFPCHeapStatus;
writeln('== 3 ==');
writeln(a.MaxHeapUsed);
writeln(a.CurrHeapUsed);
sl.Add('To beer or not to beer? That is the question!');
a := GetFPCHeapStatus;
writeln('== 4 ==');
writeln(a.MaxHeapUsed);
writeln(a.CurrHeapUsed);
Readln;
end.
and output:
== 1 ==
2448
2448
== 2 ==
3488
3488
== 3 ==
3568
3568
== 4 ==
3616
3616
And another test with large text file:
sl.LoadFromFile('tolstoy - war and peace.txt');
a := GetFPCHeapStatus;
writeln('== 4 ==');
writeln(a.MaxHeapUsed);
writeln(a.CurrHeapUsed);
Output:
== 3 ==
3568
3568
== 4 ==
8837104
4643776
File size: 3,1 Mb (3 280 005 bytes) (ansi encoding)
来源:https://stackoverflow.com/questions/15622455/how-can-i-find-out-how-much-memory-is-used-by-a-specific-component-or-class