Recent

Author Topic: How to free memory after destroying components  (Read 5586 times)

rayanAyar

  • New member
  • *
  • Posts: 7
How to free memory after destroying components
« on: June 16, 2011, 04:44:25 am »
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.

Code: [Select]
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.

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: How to free memory after destroying components
« Reply #1 on: June 16, 2011, 02:32:23 pm »
Yes, after first "Button2Click and Button3Click" memory stay allocated but when I repeat several times it does not grow more.

I tried to put
Code: [Select]
  getmem(P, 40000000);
  exit;
to Button2Click and
Code: [Select]
  freemem(P, 40000000);
  exit;
to Button3Click (allocates one big block instead of 1000 Edits) and number seems much better.
I think memory is fragmented and cannot be given back to OS. But I don't know what is exact freepascal allocation strategy.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

rayanAyar

  • New member
  • *
  • Posts: 7
Re: How to free memory after destroying components
« Reply #2 on: June 16, 2011, 03:27:06 pm »
Yes, after first "Button2Click and Button3Click" memory stay allocated but when I repeat several times it does not grow more.
Yes, I know - it does not grow. And 30MB of lost memory in example above is not a reason to worry.
But memory allocation may be much bigger, application must work 24/7 and some of our workstations has 512MB RAM.

So I would like to control memory allocation. If it possible.

 

TinyPortal © 2005-2018