I need to create and destroy components at runtime. Sometimes many components. But after ".Free" components memory doesn't free.
FPC Heap became same size as before creation of components. But OS reports that memory of application became much bigger than before creation.
For example:
- application start
CurrHeapSize: 2 260 992; CurrHeapUsed: 561 136; CurrHeapFree: 1 699 856; ResidentSetSize: 11 628 kB; DataSegment: 3 456 kB;
- create 5000 components (Button2)
CurrHeapSize: 9 011 200; CurrHeapUsed: 8 091 696; CurrHeapFree: 919 504; ResidentSetSize: 49 608 kB; DataSegment: 40 808 kB;
- free all created components (Button3)
CurrHeapSize: 2 654 208; CurrHeapUsed: 560 304; CurrHeapFree: 2 093 904; ResidentSetSize: 43 228 kB; DataSegment: 34 212 kB;
30MB lost.
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
ExtCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton; //Show memory usage
Button2: TButton; //Create components
Button3: TButton; //Free components
Edit1: TEdit; //Number of components to create
Memo1: TMemo;
ScrollBox1: TScrollBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
//Show memory usage
var
slProc: TStringList;
FPCHeapStatus: TFPCHeapStatus;
sTmp: String;
begin
sTmp:= '';
FPCHeapStatus:= GetFPCHeapStatus;
sTmp:= sTmp + 'CurrHeapSize: ' + IntToStr(FPCHeapStatus.CurrHeapSize) + '; ';
sTmp:= sTmp + 'CurrHeapUsed: ' + IntToStr(FPCHeapStatus.CurrHeapUsed) + '; ';
sTmp:= sTmp + 'CurrHeapFree: ' + IntToStr(FPCHeapStatus.CurrHeapFree) + '; ';
{$IFDEF UNIX}
slProc:= TStringList.Create;
slProc.LoadFromFile('/proc/self/status');
slProc.NameValueSeparator:= ':';
sTmp:= sTmp + 'ResidentSetSize: ' + Trim(slProc.Values['VmRSS']) + '; ';
sTmp:= sTmp + 'DataSegment: ' + Trim(slProc.Values['VmData']) + '; ';
slProc.Free;
slProc:= nil;
{$ENDIF}
Memo1.Lines.Add(sTmp);
end;
procedure TForm1.Button2Click(Sender: TObject);
//Create components
var
editChild: TEdit;
lCntr: Longint;
begin
ScrollBox1.AutoScroll:= False;
for lCntr:= 1 to StrToIntDef(Edit1.Text, 1000) do
begin
editChild:= TEdit.Create(ScrollBox1);
editChild.Name:= 'ctrl' + IntToStr(lCntr);
editChild.Top:= editChild.Height * (lCntr - 1);
editChild.Text:= 'ctrl' + IntToStr(lCntr);
editChild.Parent:= ScrollBox1;
end;
ScrollBox1.AutoScroll:= True;
end;
procedure TForm1.Button3Click(Sender: TObject);
//Free components
var
compChild: TComponent;
lCntr: Longint;
begin
ScrollBox1.AutoScroll:= False;
for lCntr:= ScrollBox1.ComponentCount downto 1 do
begin
compChild:= ScrollBox1.Components[lCntr - 1];
compChild.Free;
end;
ScrollBox1.AutoScroll:= True;
end;
end.
Lazarus 0.9.30 GTK2, Debian/Ubuntu i386/amd64.