Quick question

BlitzMax Forums/BlitzMax Beginners Area/Quick question

Kryzon(Posted 2009) [#1]
Hello all,

venturing my way through Max, I haven't found an answer to this question: how to delete type instances that are not in any list whatsoever?

Say the following:
Global Character:TImage = LoadImage("character.bmp")
Now let's say that this "Character" image object has served it's purpose in the game and I don't need it anymore (but the game will still go on). How would I free it?

From what I've read on the subject, the author would attach the objects to TLists, so he could use RemoveLink. There isn't any information regarding single objects (like TImages or TSounds).


Brucey(Posted 2009) [#2]
Use
Character = Null

Assuming there are no other references to the image, the garbage collector will free it up at some point.


Dabhand(Posted 2009) [#3]
Then maybe use GCCollect() to run the garbage collector (Otherwise, like Brucey mention, just wait for it to clear itself), but you'll need to use this when in a loop, or you'll end up with a memory leak on your hands e.g.

SuperStrict

'No memory leak
For Local loop:Int = 1 To 10
	Local str:String = "Hello"
	str = Null
	GCCollect
	Print GCMemAlloced()
Next

Print ""

'Memory leak
For Local loop:Int = 1 To 10
	Local str:String = "Hello"	
	str= Null
	'GCCollect <--- commented out
	Print GCMemAlloced()
Next


Dabz


Kryzon(Posted 2009) [#4]
That's great about the '=Null'. Thanks for the info.

About the 'memory leak' part: if my GC is set to "Automatic" mode, do I still need to use GCCollect() ?


Brucey(Posted 2009) [#5]
but you'll need to use this when in a loop, or you'll end up with a memory leak on your hands e.g.


That's incorrect. There will be no memory leak if GC is set to Automatic mode - which is the default.

Kryzon is correct to assume the GC will correctly collect these objects once there is no reference to them - which is the whole point of the garbage collector :-)


dmaz(Posted 2009) [#6]
I'd ask how are you coding this that you think you need to "delete" it? there are very few reasons for you to null your references in a GC'd environment. putting all the blah=null in there is messy and ugly and since there should be no reason to do it, don't do it.

once any single reference (as long as you're not creating pointers) falls out of scope, the object will be cleaned up.

use the GC. people are too worried about memory leaks... they are pretty hard to come by in blitz unless you are doing cyclic references or pointers. one thing to remember, the GC cleans up periodically and this is a good thing and it's done that way for performance. Dabhand's example doesn't have a leak and further, there is no reason for "str = Null" in that code.

this code will show you how the GC operates... as long as the second number stabilizes, there is no leak.
Graphics 640,480
Local maxmem:Int

While Not KeyHit(KEY_ESCAPE)
	For Local loop:Int = 1 To 100
		Local str:String = "Hello"
	Next
	
	Local mem = GCMemAlloced()
	maxmem = Max(maxmem,mem)
	DrawText mem+" -> "+maxmem,10,10
	Flip
	Cls
Wend



Kryzon(Posted 2009) [#7]
I'd ask how are you coding this that you think you need to "delete" it? there are very few reasons for you to null your references in a GC'd environment. putting all the blah=null in there is messy and ugly and since there should be no reason to do it, don't do it.


For example, an "option-toggling" sound-effect of the main menu. Once the game begins (a small game, one that doesn't have the feature of getting back to the main menu), I wouldn't need that sound anymore.


once any single reference (as long as you're not creating pointers) falls out of scope, the object will be cleaned up.


I guess that settles it out. If I stop using that sound completely [or Null it], the GC will free it for me.

Thanks all for the help.


dmaz(Posted 2009) [#8]
For example, an "option-toggling" sound-effect of the main menu. Once the game begins (a small game, one that doesn't have the feature of getting back to the main menu), I wouldn't need that sound anymore.
right, so if your sound is a local variable in a function, then once you exit that function it will be cleaned up. if you are loading the sound outside any functions then the local scope is the application and you would have to Null it if you wanted it cleaned... or if you just play it once (like a background snd) then doing
PlaySound LoadSound("c:\someplace\sound.wav")
will clean it up as well.


matibee(Posted 2009) [#9]
On the topic of forcing clean-up of objects, I might have a case...

Say I've got a big background image that I want to replace;

' initial loading..
Global img:TImage = LoadImage( "big1.jpg" )

Then later I want to unload and replace it...
img = LoadImage( "big2.jpg" )

The old object will be cleaned up, but what about the occupied video memory waiting for the GC to kick in? Supposing there's not enough vid mem to load the second image without clearing out the first, what's the recommended action? this..

'unload and replace
img = Null
GCCollect
img = LoadImage( "big2.jpg" )

Cheers,


Dabhand(Posted 2009) [#10]

Dabhand's example doesn't have a leak and further.



SuperStrict

'No memory leak
For Local loop:Int = 1 To 10
	Local str:String = "Hello"
	str = Null
	GCCollect
	Print GCMemAlloced()
Next

Print ""

'Memory leak
For Local loop:Int = 1 To 10
	Local str:String = "Hello"	
	str= Null
	'GCCollect <--- commented out
	Print GCMemAlloced()
Next


Output:


17858
17858
17858
17858
17858
17858
17858
17858
17858
17858

17880
17902
17924
17946
17968
17990
18012
18034
18056
18078


So what is actually happening there then?

Just curious, because I always took that for a leak.


there is no reason for "str = Null" in that code.



lol, thats a bit of a habit, I generally do that as soon as I know I'm finished with an object.

Dabz


Brucey(Posted 2009) [#11]
So what is actually happening there then?
Just curious, because I always took that for a leak.

Remember that it doesn't garbage-collect constantly - which would slow it down. So you get a small build-up of objects, before it decides to have a clean-up.

If you run the second loop for long enough, you'll see that the memory will rise and fall over time, which is typical for most garbage-collection based frameworks.


Dabhand(Posted 2009) [#12]

Remember that it doesn't garbage-collect constantly - which would slow it down. So you get a small build-up of objects, before it decides to have a clean-up.

If you run the second loop for long enough, you'll see that the memory will rise and fall over time, which is typical for most garbage-collection based frameworks.



Ahh, right, gotcha! ;)

Cheers for, ahem, pardon the pun... Clearing that up for me! :)

Dabz


Kryzon(Posted 2009) [#13]
Just so I don't open a whole new thread for it, I'd like to ask what is the equivalent of Blitz3D's ":" in Max?

(for making multiple statements in a single line).


Brucey(Posted 2009) [#14]
semi-colon ";"


Kryzon(Posted 2009) [#15]
Thanks a bunch, Brucey.