The dreaded Garbage Collector

Monkey Targets Forums/Android/The dreaded Garbage Collector

Nobuyuki(Posted 2012) [#1]
oh my gooooooood. My project's finally starting to reach the point where the GC is getting extremely aggressive towards it. Does this happen to everyone at some point? I'm looking for some tool that can maybe help me profile where the bottleneck is in my code, or some advice on how to use ddms to properly profile my app:



What tools and techniques do you guys have to reduce the number of times the GC sweeps your app? I wish I could tell it to hold off on a sweep until a specific time. My game does a lot of vector calculations with objects, so I'm wondering if having the GC go crazy like this is unavoidable.....


slenkar(Posted 2012) [#2]
Recycle vector Objects


Nobuyuki(Posted 2012) [#3]
allllllllllocations everywhere, everywhere.

I've done some profiling and some other things recently, and it does seem like caching the vector objects improves the situation somewhat. Here are some resources to help people struggling with this crap:

http://developer.android.com/guide/practices/performance.html
http://www.youtube.com/watch?v=U4Bk5rmIpic&feature=player_embedded

Some of it is java-specific, but the big things to note here are that short-lived object allocations will cause the GC to act up quite a bit. Reducing the number of allocations made on the short term in your game loop will reduce the number of hiccups. The only way to prevent any hiccups, though, would be to have no allocations being made while the game is "in play".

This kinda requires one to change their coding style a bit such that pretty much everything relies on cached objects on a "screen" level. Such management can become a bit of a pain, and I think it shouldn't be necessary if you're just starting out, but it is something to be aware of. Once your game reaches any level of complexity, you -will- start having these issues on android, and the way to tackle them will probably involve caching some of your objects and re-using them.

Designing a good object-oriented game might sometimes clash with this notion unless you can supply references to your cache arrays, so that instances of your objects have something to work with when doing certain calculations. Something to consider when creating game objects that have instance-level mutator methods, as my Vec2 class has.

For those of you who use my Vec2 class (in the code snippets forum), be aware that Reflect as a mutator method calls a number of short-lived vec2 objects, due to the OO way it was designed. Here is an android-specific version of Reflect which takes a pre-initialized array of vec2s (basically, a vector cache) as an argument:

[monkeycode]
' ANDROID-SPECIFIC MODIFICATION: This version of Reflect takes a reference to a vector cache, to reduce
' strain on the Android Garbage Collector. This may also be useful for xna target.
Method Reflect:Void(v:Vec2, vectorCache:Vec2[], calcNormal:Bool = False) 'Reflects Self against normal vector v.
vectorCache[0].Set(Self)

If calcNormal = True Then 'calculate the normal from surface v instead.
vectorCache[1].Set(-v.y, v.x) 'Right-handed normal of v
'Project self to n
Local n:Vec2 = vectorCache[1]
n.Scale( Dot(Self,n) / Dot(n,n) )
Set (n)
Else
'Project self to n
vectorCache[1].Set(v.x, v.y)
Local n:Vec2 = vectorCache[1]
n.Scale( Dot(Self,n) / Dot(n,n) )
Set (n)
End If

Scale(2); Minus(vectorCache[0])
End Method
[/monkeycode]

You can add this modification safely to vec2.monkey without any other changes; the method signature is different, so it acts as an overload to the existing Reflect method. In your code, simply change/add to the 2nd argument the location of your Vec2 cache.


Sledge(Posted 2012) [#4]
The only way to prevent any hiccups, though, would be to have no allocations being made while the game is "in play".

This kinda requires one to change their coding style a bit such that pretty much everything relies on cached objects on a "screen" level. Such management can become a bit of a pain, and I think it shouldn't be necessary if you're just starting out, but it is something to be aware of.

I think it's a common mistake amongst game developers starting out with a managed language, that there's this assumption that OOP should mean that you can create and free objects in the game-loop willy nilly and the garbage collector should magically cope. Even with very capable hardware it's a poor paradigm (you're quite correct about XNA) and on mobile... eugh *crunch!* I sympathise, though, because it's horrible, after discovering OOP and thinking that everything is going to be so easy now, to suddenly realise that you're still going to have to cache and pool everything for performant games -- we all go through it :D