SRL Archive - OSR Help

DON'T Free your DTM's or Bitmaps!


Daniel

2012-04-23 03:06:48

Don't Free Your DTMs/Bitmaps!




Time and time again, I get (or see) people complaining about an error in their scripts relating to the title. Most of the time, it's due to the scripter having FreeDTM or FreeBitmap in their scripts. So, DON'T put them in your scripts! Sure it may be good practice too, especially if you plan to move away from the safety of the Simba development environment, but when in your script, especially if you're a beginner, DON'T free them! Yes, any of them!

No, it won't cause memory leaks. Not at least if you load them properly! What I mean by this is DON'T constantly call DTMFromString or BitmapFromString in your scripts. Only call them once, and make sure they're only being called once!

Good:
procedure LoadStuff;
begin
DTM1 := DTMFromString('340394u23hf3o23h892y389yh32h327c23cr23rg23c\==');
DTM2 := DTMFromStrign('3klfnsjht8o43to8y438thu43hf7syiouoy2492i3uyf27q\==');
Bitmap1 := BitmapFromString('q34837r2o3ijfhfiweuyirh2iygirh23grg23i6rgurbui43gi8giuwefhxguwegrugwurguwgbu\==');
Bitmap2 := BitmapFromString('324y3urhfshfiywuichfchfgcyi1y4t718749QRASULUFHGIAWEU6ACRYIQUY\==');
end;

procedure FindStuff;
begin
if(FindBitmap(Bitmap1, x, y)) then
…
if(FindDTM(DTM1, x, y...)) then
…
end;

begin
LoadStuff;
repeat
FindStuff;
Until(AllPlayersInactive);
end.

Bad #1:
begin
repeat
LoadStuff; // It's in a loop! NEVER do this!
FindStuff;
Until(AllPlayersInactive);
end.

Bad #2:
procedure FindStuff;
begin
// You're loading a bitmap here!
Bitmap1 := BitmapFromString('q34837r2o3ijfhfiweuyirh2iygirh23grg23i6rgurbui43gi8giuwefhxguwegrugwurguwgbu\==');
if(FindBitmap(Bitmap1, x, y)) then
…

// You're loading a DTM here!
DTM1 := DTMFromString('340394u23hf3o23h892y389yh32h327c23cr23rg23c\==');
if(FindDTM(DTM1, x, y...)) then
…
end;

begin
repeat
FindStuff;
Until(AllPlayersInactive);
end.

Notice that in the “good” example, that I am only loading things once. I am doing it at the very beginning of the script, in a separate procedure. I have not put it inside a loop, and notice that I'm also not free'ing anything either.

So, what's the big deal?
[INDENT]It will save a lot of time and effort for you (and others if you ask them for help) in fixing/maintaining your scripts. Memory management can be a hassle, trust me, and getting people who don't know how to properly manage what they load is even more of a hassle. So, it's better to not try to manage memory in your scripts, that way you won't get any problems/errors relating to this subject (DTMs/Bitmaps) when you go to run your script.[/INDENT]

But won't it cause memory leaks and stuff?
[INDENT]A memory leak is when something is loaded, but not being freed. If you load [the same] things constantly (i.e. more than once), your memory in Simba will undoubtedly grow minorly (mostly minorly). That is why you should load them only once! And then leave it at that and do nothing else to it (except using it to find things)!

Simba automatically unloads (free's) ALL left over loaded DTMs/Bitmaps in your scripts. It's better to let Simba do it, than for you to do it :)[/INDENT]

REMEMBER to:
  • Have every Bitmap AND DTM you want to load in one procedure.
  • Call that procedure AT THE BEGINNING of your script in the begin end clause.
  • DON'T call it repeatedly, and,
  • DON'T Free your DTMs OR Bitmaps!

Good day :)

TomTuff

2012-04-23 03:10:09

Proof?

masterBB

2012-04-23 03:13:20

From: TomTuff
Proof?


I believe he meant that cause the bitmaps and dtms we use take such small space in your memory, it's advisable to not free them when you are a beginner.

Daniel

2012-04-23 04:07:31

From: masterBB
I believe he meant that cause the bitmaps and dtms we use take such small space in your memory, it's advisable to not free them when you are a beginner.


People attempt to manage the memory themselves, when it's most likely best left for Simba to do such a thing and other cleanup tasks when the script finishes. I've seen many that load the object in their find procedure, forget to free it and repeatedly call that method. And what I'e seen even more, is people loading their objects once, then in their find method (once found), will free that object and call that method again without loading the object again.

That's why I believe it's better to just let Simba do all the dirty work for you (well, beginners mostly). :)

cycrosism

2012-04-23 04:12:14

The way I have always done it since I have been scripting since 2008 is this:

1. Declare bitmap
2. Search for bitmap
3. Free bitmap

This process has never given me any errors (bitmap or memory related) ever. But that was with SCAR. Simba may be different.

Daniel

2012-04-23 04:19:26

From: cycrosism
The way I have always done it since I have been scripting since 2008 is this:

1. Declare bitmap
2. Search for bitmap
3. Free bitmap

This process has never given me any errors (bitmap or memory related) ever. But that was with SCAR. Simba may be different.


Or, you could declare them all at the beginning and free them all at the end, much to the same affect :)

However, what a lot of people do repetitively is either 1 and 2, or 2 and 3. :p Hence the purpose of this thread.

Sex

2012-04-23 04:21:24

I'm still gonna free 'em >.>.

Total

2012-04-23 04:43:21

Yeah I just have a load at the beginning and then I add on terminate a freeing procedure, but I'm pretty sure simba auto frees them when you end the script but whatever. :p

cycrosism

2012-04-23 06:10:07

From: Daniel
Or, you could declare them all at the beginning and free them all at the end, much to the same affect :)

However, what a lot of people do repetitively is either 1 and 2, or 2 and 3. :p Hence the purpose of this thread.


That is the way it should be done.

Declared at the start, used throughout the script, free them all at the end.

OR

Declared, used at that very moment, free them straight after.

Either of those should work fine.

Gu3st...

2012-04-23 06:28:52

From: cycrosism
That is the way it should be done.

Declared at the start, used throughout the script, free them all at the end.

OR

Declared, used at that very moment, free them straight after.

Either of those should work fine.
The "1. Load, 2. Search, 3. Free"-method is definitely the best, but when dealing with a small amount (less than 10) of tiny bitmaps or dtms then the difference is nearly undetectable.

Freddy1990

2012-04-23 12:55:16

The fact that SCAR and Simba free resources after scripts run is a feature to prevent memory leaks in case the scripter does not do this manually… You should however make it a habbit to always do this. If you keep creating bitmaps and not free them when you no longer need them, the memory will get clogged up and the application will crash.

Brandon

2012-04-23 13:10:46

Why would you not free them consider this case:


Function SelectPotion(Potion: String): boolean;
var
DTM: Integer;
begin
case Lowercase(Potion) of

1: DTM:= DTMFromString('...............');

2: DTM:= DTMFromString('...............');

3: DTM:= DTMFromString('...............');

4: DTM:= DTMFromString('...............');

5: DTM:= DTMFromString('...............');

end;

DrinkPotion(DTM); //Iunno.. Some procedure that uses the DTM;
FreeDTM(DTM);
end;

Could be pretty useful I suppose. You just get the DTM you want via a case statement and free it after use.. I suppose your saying that I should just grab the DTM at the very beginning of the script depending on the option chosen and then free it at the end..

BUT what if our parameters change? What if every loop, the potion string changes? Then you have no choice but to free it..

Something such as:


Function SwitchPotions: Boolean;
var
I: Integer;
begin
For I:= 0 To High(10) do
begin
case I of
1: SelectPotion('dsgdsgsdgs');

2: SelectPotion('someother crap');

3: SelectPotion('A different One');
end;
end;
end;

Would screw the user over if they do not free it. I think it'd be best to learn memory management as soon as possible.. I mean yeah you can let the "garbage collection" do it but in some cases well.. That won't help.

I guess you might say to load all 50 DTM's at the beginning of the script and free 50 of them at the end and yes that would help. BUT that would depend on how long the script will run for and how many times you would call that procedure/function and it'd depend on what ones may or may not be used. It's a matter of how the function will be used and how many times it'd be called.