GC does not work how I thought it did
BlitzMax Forums/BlitzMax Programming/GC does not work how I thought it did
| ||
Note: I'm not using threading here, so standard GC is being used. Consider this code: Strict Local x:myType For Local N:Int = 1 To 50 x = New myType x.timer._ticks = 0 DebugLog "Passed iteration: " + N Next Type myType Field timer:ttimer Method New() Self.timer = CreateTimer(10) End Method End Type Now, I'm fully aware of the limit on the number of timers you can use, but that's not the issue - it just serves to highlight it. Using the code above, only one instance of myType should ever exist, and therefore, only one timer should ever exist. After exactly 16 iterations every time, I get "attempted to access field or method of null object". Why? Surely only one timer exists? The code obviously executes in a fraction a second, but even in a real world scenario (of playing a game repeatedly over several minutes), it still dies after 16 iterations. I use two timers, and that's all there should ever be in existence, so should not be any problems. [edit] Just tried threaded GC with identical results so I don't think its actually a GC problem. Also, no amount of manual garbage collecting seems to fix this, either. |
| ||
You can't make assumptions about when the garbage will be cleared. If you put a GCcollect() <assuming it still exists in Blitz?> in the loop, it may stop the error. |
| ||
You should call StopTimer( X.Timer ) before "freeing" it by overwriting your variable X with a new type. Else it will probably not get GCed I think ^^ |
| ||
You can't make assumptions about when the garbage will be cleared. If you put a GCcollect() <assuming it still exists in Blitz?> in the loop, it may stop the error. I would have thought it would be safe-ish to assume that GC would run at least once over a period of several minutes?As I said (in my edit, so you may have missed it), manually calling GCCollect() doesn't improve the situation. You should call StopTimer( X.Timer ) before "freeing" it by overwriting your variable X with a new type. Oddly, that works - thanks. Be nice if GC didn't pick and choose what it wants to clean up. |
| ||
I think timers have to be destroyed manually with StopTimer... this works fine..Strict Local x:myType For Local N:Int = 1 To 50 If ( x ) StopTimer( x.timer ) End if x = New myType x.timer._ticks = 0 DebugLog "Passed iteration: " + N Next Type myType Field timer:ttimer Method New() Self.timer = CreateTimer(10) End Method End Type |
| ||
Sorted. Thanks all. |