PDA

View Full Version : How to Free DTM/Bitmap's the correct way



Sir Ducksworthy
03-26-2012, 08:17 PM
How to Free DTM/Bitmap's the correct way

Introduction:
Basically in this guide I am going to teach you about a function called AddonTerminate(), what it is and how to use it.

Okay, so we have our two procedures...
Firstly our procedure to Load our DTM/Bitmap's and secondly our procedure to Free them.
Example for DTM's:

procedure DTMZ;
begin
Dust:= DTMFromString('mbQAAAHicY2VgYMhiYmBIAuJCJgg7B4ifM0 DwMyB+A8SPgDjUUBpIMqFgfgZMwIgFgwEAV7cHYg==');
Choc:= DTMFromString('mbQAAAHicY2VgYMhhYmAoBOJUIE4H4jIgfg QUvwPEr4D4PhA/AWIfHQkgyYSC+RkwASMWDAYAUOoHRg==');
end;

procedure FREEDTMZ;
begin
FreeDtm(Dust);
FreeDTM(Choc);
end;


Now most people usually free them using:

begin
SetupSRL;
DTMZ;
repeat
CrushProcess;
if(Crushes+1>Howmany)then
begin
FREEDTMZ;
terminatescript();
end;
until (not Loggedin);
end.


The Problem with using that method or using this method:

begin
SetupSRL;
DTMZ;
repeat
CrushProcess;
until (not Loggedin);
FREEDTMZ;
terminatescript();
end.


Is that if the script messes up and is stuck in a loop or what not, chances are your not going to be logged out because it will keep you logged in by continuously interacting with the Rs client.
You will then terminate it manually with the Stop button on Simba:f:

Which will unfortunately leave you with Non Freed Dtm/Bitmap's
This causes excess memory usage on your computer and ultimately slows down Scripts/Simba.

To avoid this we simply need to use the function:
Addonterminate();

What this function does is it allows you to call any procedure before the script is terminated.


How do we do this?
We need to call it in our Setup in the Main Loop

For our FREEDTMZ; procedure it would look something like this:

begin
SetupSRL;
DTMZ;
Addonterminate('FREEDTMZ');
repeat
CrushProcess;
until (not Loggedin);
FREEDTMZ;
terminatescript();
end.


Congratulation's! you just saved your computer's memory :spot:
You'll notice now no matter how you stop your script all the Dtm/Bitmap's will be freed

Hazzah
04-22-2012, 06:59 PM
Well this is actually really useful and I can't believe no one has ever posted on here. On the few basic things I had used I always loaded the DTM's in the same procedure and freed them at the end of the procedure. It worked sometimes, but if you stop the script in the middle of the procedure your DTM's wouldn't be freed. This will be useful to know/use!

Abu
04-22-2012, 07:05 PM
Thanks for bumping Hazzah :)

OT: I always use this method and had to idea there was a tutorial on it. Good work leet.

+rep

BigFate
08-01-2012, 06:08 PM
Thanks I found this very useful...should be near the top it is important :)!

Ian
10-27-2012, 05:09 PM
You should link this in your signature if you have room :D

Enslaved
10-28-2012, 01:30 PM
Great job :)

mounty
11-23-2012, 05:52 PM
This has been a great help for my current script. Been getting a lot of unfreed DTMs when the script was stopped. This simple fix has now solved that.

danny2010
11-23-2012, 11:56 PM
SRL has a free procedure too FreeSRL;

DannyRS
12-05-2012, 12:54 AM
Is it just me or is this not working too gret when you have like 50 DTMs? Atleast a few seem to not get freed

Olly
12-05-2012, 03:13 AM
50 dtms.... what the..

Ian
12-05-2012, 03:35 AM
50 dtms.... what the..

Probably for his AIO bow fletcher.

heyaiam
04-16-2013, 05:21 AM
Call me stupid, I still don't know how to free...

Le Jingle
04-16-2013, 05:27 AM
Call me stupid, I still don't know how to free...

Building off the original post:


// the DTM declared globally:
var
someDTM: Integer;

// the DTM being setup for global use.
procedure SetupGlobals();
begin
someDTM := DTMFromString('the actual string goes here');
end;

// call this function when the script stops (best used with a call shown later, AddOnTerminate)
procedure FreeGlobals();
begin
FreeDTM(someDTM);
end;

// main code in script to be used:
begin
SetupGlobals(); // setups the DTM to use
AddOnTerminate('FreeGlobals'); // calls this function when the script stops (ex - it will free the DTM for us)
end.


Something like the above is a basic example/variation of what the original poster is saying. (Note this code was all typed in the browser and not compiled for test)

heyaiam
04-16-2013, 05:48 AM
Where do I put in? like what line and stuff? assuming I already have the script open? I'm really noob at this. .

heyaiam
04-16-2013, 07:46 AM
I hav no idea how to free :S
Please help! !

t4q
04-16-2013, 09:57 AM
I hav no idea how to free :S
Please help! !
after you have found your DTM add line:
freeDTM(DTMname);

heyaiam
04-16-2013, 10:50 AM
after you have found your DTM add line:
freeDTM(DTMname);

Sorry I don't quite understand what you mean by this.
I can't find anything with DTM in the scripts I wish to run.

Chris
04-16-2013, 11:20 AM
Nice guide, I've used this aswell and it's really handy.

Though you say: "You'll notice now no matter how you stop your script all the Dtm/Bitmap's will be freed"

CHALLENGE ACCEPTED

- run this:
var
s: string;

begin
DTMZ;
Addonterminate('FREEDTMZ');
s := s[0];
end.

That's how I stop my script :bart:

bgtemp
08-06-2013, 09:09 PM
What's the point of freeing stuff on terminate ,when Simba does it for you?

Zeta Matt
09-19-2013, 01:53 AM
What's the point of freeing stuff on terminate ,when Simba does it for you?

^ I also got this question :O But this is not my main point.

Also, if the point is to prevent memory leaking, this function would work only on scripts with few DTM/BitMaps being called, right? I mean, if 100 DTM's and BitMaps are called along a script and you only free them on terminate... it would cause a memory leak anyway, wouldn't it?

Zeta Matt
09-19-2013, 01:56 AM
Sorry I don't quite understand what you mean by this.
I can't find anything with DTM in the scripts I wish to run.

Read this: http://docs.villavu.com/simba/scriptref/dtm.html#freedtm
Called DTM's stay on your computer's memory. If many DTM's are piled in it, it will suffer of memory leaking, basicaly... That's why you have to free them.

bgtemp
09-20-2013, 10:12 AM
^ I also got this question :O But this is not my main point.

Also, if the point is to prevent memory leaking, this function would work only on scripts with few DTM/BitMaps being called, right? I mean, if 100 DTM's and BitMaps are called along a script and you only free them on terminate... it would cause a memory leak anyway, wouldn't it?

No, it would only build memory stack. "Leak" is when you lose access to memory region. All those 100 Bitmaps would be freed on terminate , if there were a leak they would remain after script is done ,until you close Simba.

Kasi
09-20-2013, 07:00 PM
Tend to use:


function TryFreeDTM(DTM : Integer) : Boolean;
begin
try
FreeDTM(DTM);
except
finally
end;
end;


Do the same for Bitmaps.

Zeta Matt
09-21-2013, 03:02 AM
No, it would only build memory stack. "Leak" is when you lose access to memory region. All those 100 Bitmaps would be freed on terminate , if there were a leak they would remain after script is done ,until you close Simba.

Makes sense... Anyway, it would be useless to free on terminate, then...?

Pakyakkistan
03-20-2014, 03:20 PM
This may be considered grave digging, but seeing as its a tutorial and is meant to be a learning reference; you should probably mention that you need to declare those DTMs as global variables as well. If you don't, and try declaring them as variables in each procedure you search for them, you won't ever find the DTMs because it will try to declare them as 'new' variables in each procedure. Other then that, wonderful guide! Glad it was here so I ensured I was doing it right.

Edit: Also, if you are going to continue calling for the DTMs, you'll need to Load and Free them within the 'main' loop. Or else you'll free them and gt a run-time error because you won't have any DTMs loaded.

Frement
03-20-2014, 03:33 PM
This may be considered grave digging, but seeing as its a tutorial and is meant to be a learning reference; you should probably mention that you need to declare those DTMs as global variables as well. If you don't, and try declaring them as variables in each procedure you search for them, you won't ever find the DTMs because it will try to declare them as 'new' variables in each procedure. Other then that, wonderful guide! Glad it was here so I ensured I was doing it right.

Edit: Also, if you are going to continue calling for the DTMs, you'll need to Load and Free them within the 'main' loop. Or else you'll free them and gt a run-time error because you won't have any DTMs loaded.

Thats more of a subject for DTM tutorial, rather then how to free resources properly. But yes, each of your point is valid.

Brotein
03-20-2014, 04:00 PM
Edit: Also, if you are going to continue calling for the DTMs, you'll need to Load and Free them within the 'main' loop. Or else you'll free them and gt a run-time error because you won't have any DTMs loaded.

Shouldn't you just load the DTMs before your main loop once and free them once you terminate the script. What's the point of constantly loading and unloading them?

Pakyakkistan
03-20-2014, 04:11 PM
Read this: http://docs.villavu.com/simba/scriptref/dtm.html#freedtm
Called DTM's stay on your computer's memory. If many DTM's are piled in it, it will suffer of memory leaking, basicaly... That's why you have to free them.


Shouldn't you just load the DTMs before your main loop once and free them once you terminate the script. What's the point of constantly loading and unloading them?

Assumed that not calling them would cause a stack of DTMs. I know that doing this without globally doing it would cause this. Each time you load that DTM it would add up.

Edit: For example, my Iron Knife smither, remove some of the FreeDTM procedures and watch the DTM amounts stack when you stop the script. But, like I said, I have no idea if its the same thing when you globally declare them

Brotein
03-20-2014, 04:25 PM
Assumed that not calling them would cause a stack of DTMs. I know that doing this without globally doing it would cause this. Each time you load that DTM it would add up.

Edit: For example, my Iron Knife smither, remove some of the FreeDTM procedures and watch the DTM amounts stack when you stop the script. But, like I said, I have no idea if its the same thing when you globally declare them

Why wouldn't you just declare them globally and only load them once?
program new;
var
DTM1, DTM2, DTM3 : Integer;

procedure setDTMs;
begin
DTM1 := DTMFromString('');
DTM2 := DTMFromString('');
DTM3 := DTMFromString('');
end;

procedure killDTMs;
begin
freeDTMs([DTM1, DTM2, DTM3]);
end;

begin
setDTMs;
addOnTerminate('killDTMs');
repeat
//do our stuff
until (not isLoggedIn);
killDTMs;
terminateScript;
end.

I can use those DTMs in any function or procedure and I only need to load them once, and free them once.

Sk1nyNerd
03-20-2014, 04:46 PM
Why wouldn't you just declare them globally and only load them once?
program new;
var
DTM1, DTM2, DTM3 : Integer;

procedure setDTMs;
begin
DTM1 := DTMFromString('');
DTM2 := DTMFromString('');
DTM3 := DTMFromString('');
end;

procedure killDTMs;
begin
freeDTMs([DTM1, DTM2, DTM3]);
end;

begin
setDTMs;
addOnTerminate('killDTMs');
repeat
//do our stuff
until (not isLoggedIn);
killDTMs;
terminateScript;
end.

I can use those DTMs in any function or procedure and I only need to load them once, and free them once.

thats how i do it and thats how i learned in a dtm tut, never had a script bog down or cpu shoot up

Pakyakkistan
03-20-2014, 05:35 PM
Why wouldn't you just declare them globally and only load them once?
program new;
var
DTM1, DTM2, DTM3 : Integer;

procedure setDTMs;
begin
DTM1 := DTMFromString('');
DTM2 := DTMFromString('');
DTM3 := DTMFromString('');
end;

procedure killDTMs;
begin
freeDTMs([DTM1, DTM2, DTM3]);
end;

begin
setDTMs;
addOnTerminate('killDTMs');
repeat
//do our stuff
until (not isLoggedIn);
killDTMs;
terminateScript;
end.

I can use those DTMs in any function or procedure and I only need to load them once, and free them once.

Makes sense. Didn't know, never globally declared or free'd my DTMs. This is the only global DTM tut i've looked at, thanks everyone for the pointers.

masterBB
03-20-2014, 06:13 PM
Which will unfortunately leave you with Non Freed Dtm/Bitmap's
This causes excess memory usage on your computer and ultimately slows down Scripts/Simba.[/I][/B]

All DTMs are freed when the script crashed or is stopped.

Pakyakkistan
03-20-2014, 10:44 PM
All DTMs are freed when the script crashed or is stopped.

Yea, I wasn't paying attention either. Since you have AddOnTerminate there truly isn't a need to free your DTMs in the loop repeatedly. As long as you have them freed on termination; my bad Brotein; - Thanks tho

Was thinking that they are filling memory as long as they are being 'used'.

masterBB
03-21-2014, 01:32 PM
Yea, I wasn't paying attention either. Since you have AddOnTerminate there truly isn't a need to free your DTMs in the loop repeatedly. As long as you have them freed on termination; my bad Brotein; - Thanks tho

Was thinking that they are filling memory as long as they are being 'used'.

Even without the add on terminate, simba will always free them. Filling your memory can only happen while the script is running.

Pakyakkistan
03-21-2014, 01:55 PM
Even without the add on terminate, simba will always free them. Filling your memory can only happen while the script is running.

Wait what?

You're saying that if I stop the script midway it should free my DTMs? I thought this was why you added it on terminate because it wouldn't free them?

Or are you saying that they are freed once the script is ended? Sorry for my confusion, just wanting to make sure I understand correctly.

masterBB
03-21-2014, 05:32 PM
Wait what?

You're saying that if I stop the script midway it should free my DTMs? I thought this was why you added it on terminate because it wouldn't free them?

Or are you saying that they are freed once the script is ended? Sorry for my confusion, just wanting to make sure I understand correctly.

Let me explain you a bit how simba handles bitmaps and dtms. When you create a DTM or Bitmap(resource from this moment on) with most of the common used functions, you will get an integer instead of a TMufasaBitmap or TDTM. This integer is not a pointer, nor is it the resource itself(obviously ;) ). Simba manages a list(array) with all the DTMs and a list with all the bitmaps. The integer you get returned is simply the index/place in the array where the resource is stored.

When the script threads end either by being stopped or crashing, simba will free all the bitmaps and dtms it still has in those lists. So it will not cause memory leaks. When this happens simba will display a line you are probably familiar with. ("DTMs not freed..")

So when does freeing actually matter? Assume the following code is used:


repeat
wait(50);
bankersDTM := DTMFromString('avraagaregarega');
until(FindDTM(bankersDTM )); //arrived at bank
FreeDTM(bankersDTM);


If the script continues to run this code the memory will be filled with the same DTM of the bankers... Only the last one is freed. I actually see this happen every now and then.