More Memory Questions

BlitzMax Forums/BlitzMax Programming/More Memory Questions

Sean Doherty(Posted 2007) [#1]
The following code, compiled in non-debug mode, initially allocates 37K on memory. However, as the it runs it show that it has 50K to 60K of allocated memory.

1) Why?
2) Is there a way to change the code so the memory allocated is static?

SuperStrict


Global g_iInitialMemory:Int

Graphics 1024, 768,0, 0

'Reset & store the initial memory value.
GCCollect()
g_iInitialMemory = GCMemAlloced()

Repeat

	SetBlend SOLIDBLEND
	
	DrawText("Initial Allocated Memory = " + g_iInitialMemory, 10, 10)
	DrawText("        Allocated Memory = " + GCMemAlloced(), 10, 25)

	Flip -1
	Cls
Until KeyHit(KEY_ESCAPE)


Thanks


JazzieB(Posted 2007) [#2]
GC doesn't work every frame unless you force it to, which is why your memory goes up to a certain point and then drops. If you put a GCCollect in your main loop, you'll get a static value.


CS_TBL(Posted 2007) [#3]
GC is weird. Why does the GC pile-up when hovering the mouse over a canvas? Why is RAM being consumed by just doing that?


SSS(Posted 2007) [#4]
I'd imagine it's because you're generating MOUSE_OVER events each frame or something.


Grey Alien(Posted 2007) [#5]
and because you are creating strings to output with drawtext. Also draw text may make things that consume memory.


Michael Reitzenstein(Posted 2007) [#6]
You really, really don't want to be worrying about this. The BlitzMax GC is optimised for actual programs rather than test demos like this, but it does work (except it doesn't handle circular references) and works well. I don't even know how much memory my game takes, because last time I checked I realised it just doesn't matter.

Finish the game and if it's slow, optimise then!


Sean Doherty(Posted 2007) [#7]
@Michael, Is Darwin The Monkey a BlitzMax game?

I seems to matter in my game, I've used a lot of circular reference; things like world has a unit and unit is part of the world. Does anyone know why circular references are not freed?


Brucey(Posted 2007) [#8]
Does anyone know why circular references are not freed?

Because of the very fact that they are circular. ie. A points to B which points to A.

If B is a child of A, then you can build into your A.free() a case where it removes it's children, which in turn causes say, B.free() to be called, which you set to null out the reference to A.

Unless you build your code in such a way as you know that your own code will clean itself up properly, you should really stay clear of circular references if you can. (It's certainly possible to design code that doesn't need them)


Sean Doherty(Posted 2007) [#9]
@Brucey, Don't other languages, such as Java, handle freeing circular references? I'm thinking is A and B or only pointing at each other, the runtime should be able to free both references; or not?


Brucey(Posted 2007) [#10]
It depends how you implement the garbage collector.
Java didn't used to be able to handle circular references (in 1.1), but they changed it so that instead of just strong references, Java could handle different kinds - soft, weak and phantom. This way the garbage collector can determine if a specific object is accessible any more or if its status can be changed to allow it to be GC'd. (although it's up to the VM to decide when, if at all, it is GC'd).

I imagine that in BlitzMax all references are strong, and that's why, when you create a circular reference, you will have to break it yourself when you want the GC to clean up your objects - which isn't such a big deal if you build that capability into your design.

So in Max, read -> circular references are a potential memory leak.


Gabriel(Posted 2007) [#11]
I've requested weak references for BMax before, but no reply. I don't see any necessity for it to manage circular references though. If your design requires circular references ( and I accept that for the sake of speed, this does happen ) then you know you've done it, so you know you have to break them when you're finished with the objects involved.

Weak references would be handy for writing modules, libraries, etc where you may wish the module or library to hold internal references to objects which can also be used by the person using your library too. This way the person using your library can allow his or her own objects to be disposed as one should in a managed environment. If the engine needs a copy of those objects for it's internal purposes, they should be weak references or else they will never be collected and you have to have an explicit destroy method for your user to call, which defeats the object of having an automated GC.


Dreamora(Posted 2007) [#12]
Or you have to use funny hacks like object[-8] :- 1 ...


Grey Alien(Posted 2007) [#13]
Darwin is Delphi.

But yeah I agree with Michael, I used to be very careful to manually free all this stuff up (old habits) and then I did some very thorough testing and realised that I didn't need to do any of it, the GC did it all for me. The only use of freeing stuff up is if you want to free up some memory mid game (maybe when changing screens) and load the screen up dynamically each time.


Gabriel(Posted 2007) [#14]
Right, or the hacks with the object pointer. And they could stop working at any time, particularly with Mark working with reflection and meta information in types.