PDA

View Full Version : Memory and allocating/releasing..



HopeDagger
03-05-2005, 09:42 PM
Does memory dynamically allocated (via Create and New) in Delphi automatically get unallocated when your program ends, or must that be done manually?

If so, then is there a procedure to get the current amount of free system memory? (I recall there being one in FreePascal..) I'd like to compare how much memory I'm chewing up and not releasing. ;)

Thanks!

cairnswm
04-05-2005, 04:48 AM
My understanding is that all memory used by an application (of any sort - variables and dynamic allocation) all happens in the Executables memory space. when the application ends all that memory is then freeded by the operating system .

Write an app that creates a couple of MB of memory dynamically - then kill it in the task manager and watch what happens in the performance window - All the memory comes back.


Here is an example
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;

type
TForm1 = class(TForm)
BitBtn1: TBitBtn;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}


type
PListEntry = ^TListEntry;
TListEntry = record
Next: PListEntry;
Text: string;
Count: Integer;
A: Array[1..1000000] of Integer;
end;


var
List, P: PListEntry;

Procedure Load;
Var
I : Integer;
begin
New(P);
P^.Next := List;
P^.Text := 'Hello world';
P^.Count := 1;
For I := 1 to 1000000 do
P^.A[I] := I;
List := P;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Load;
end;

end.


All it requires is a form with a single button. Each time you click the button it allocates over 4MB of memory using NEW. I ran the program up to 400MB of memory and then used task manager to kill it. I Seemed to get it all back.

{MSX}
04-05-2005, 07:11 AM
Does memory dynamically allocated (via Create and New) in Delphi automatically get unallocated when your program ends, or must that be done manually?

If so, then is there a procedure to get the current amount of free system memory? (I recall there being one in FreePascal..) I'd like to compare how much memory I'm chewing up and not releasing. ;)

Thanks!

The memory must always be unallocated manually. Every object you create must be freed and each New need it's Dispose (it was New/Dispose, wasn't it?)
This is expecially true in games, where you have the main loop that is called over and over. Even a little memory leak (unallocation) in that loop will eat up all the memory in short time.

I don't remember of a procedure to get free memory amount. You should probably use your operating system's own call.

As cairnswm said, all your program's memory is unallocated when the program terminates.

Bye!

tux
04-05-2005, 08:42 AM
a bit of googling gave me this


procedure TForm1.BitBtn1Click(Sender: TObject);
var
Status : TMemoryStatus;

begin
Load;

Status.dwLength := SizeOf(TMemoryStatus);
GlobalMemoryStatus(Status);

Label1.Caption := Format('Memory Load :: %d percent', [Status.dwMemoryLoad]);
Label2.Caption := Format('Total Physical :: %f mb', [Status.dwTotalPhys / 1024 / 1024]);
Label3.Caption := Format('Availible Physical :: %f mb', [Status.dwAvailPhys / 1024 / 1024]);
Label4.Caption := Format('Total Page File :: %f mb', [Status.dwTotalPageFile / 1024 / 1024]);
Label5.Caption := Format('Availible Page File :: %f mb', [Status.dwAvailPageFile / 1024 / 1024]);
Label6.Caption := Format('Total Virtual :: %f mb', [Status.dwTotalVirtual / 1024 / 1024]);
Label7.Caption := Format('Availible Virtual :: %f mb', [Status.dwAvailVirtual / 1024 / 1024]);

HopeDagger
04-05-2005, 04:57 PM
The memory must always be unallocated manually. Every object you create must be freed and each New need it's Dispose (it was New/Dispose, wasn't it?)

Then..


As cairnswm said, all your program's memory is unallocated when the program terminates.

Doh, perhaps I'm just not following here. First you said that memory deallocaton MUST be done manually at all times, then said that all of the taken memory gets unallocated automatically when your program ends. So why worry so much about it if it gets cleared up by the program anyways?

@tux: Awesome! Thanks. :)

Edit: Why aren't my Quote blocks showing? :/

{MSX}
04-05-2005, 05:13 PM
Doh, perhaps I'm just not following here. First you said that memory deallocaton MUST be done manually at all times, then said that all of the taken memory gets unallocated automatically when your program ends. So why worry so much about it if it gets cleared up by the program anyways?


Ehehe i'll try explain this apparent contraddiction.

The first fact is that while you're application is running, no memory will be automatically freed. So if your application leaks memory on it's main loops, it will keep wasting memory all the time that it is running. A game can easily eats lots of mega each second. If it's run for hours it can finish all avaiable memory.
You could say that it's not a great problem but think that there are lots of program/processes running on a system, and they need their memory too.
So it's always wrong to not release memory.

All this reasoning applies on a program in execution. When a program terminates, the OS releases all memory allocated (and all other resources too). This to say that if you forget to release by yourself you will not waste memory indefinitely :P The user can always kill the program and get the memory back.
But this don't make it less important to always release everything while the program is running. :D

Almindor
04-05-2005, 09:51 PM
I've found a VERY good basic way of writing classes to eliminate memory leaks(apart from using heaptrace).

ALWAYS put your Create and Destroy methods beside each other. This way you can see if you didn't forget something.

I know that most of the time, memory leaks are cause by more severe errors, but alot of stupid mistakes can be avoided this way.