|
Hi There I am developing for iOS, so I want to have as few spikes as possible... I see that I am growing my allocated heap at a rate of a few K every few seconds. I cannot at this stage determine why this is. The MAX heap size is tiny also, I have around 500K of headroom before a collect will occur. Following the advice I had read in the Unity docs on maintaining performance I added a GC.Collect() every 30th frame. However this seems to take a huge amount of time, like 60MS every single time I issue a collect (iPhone 3G S) and there's typically only a few K to actually collect. I was rather expecting more in the region of the 5MS suggested. I am enabling ENABLE INTERNAL PROFILER to see these numbers. Is this because we have a big app (maybe 50MB) and so we have a small heap size and a lot of RAM to check over during a collect? Has anyone else experienced this? Also, I have assumed that the heap sizes are in bytes, could anyone confirm this? Thanks Bovine
(comments are locked)
|
|
Okay, so I'll answer my own question here, sorry it's probably obvious but hopefully will help someone else: See the docs here: http://unity3d.com/support/documentation/Manual/iphone-Optimizing-Scripts.html It's slow because as mentioned in this video... http://unity3d.com/support/resources/unite-presentations/optimizing-for-unity-iphone-1.5.html ...the whole heap has to be considered and as my heap is not 200K but 3.5MB it's like 10 times the cost. It seems calling Collect() is best done between level loads and obviously it's best to avoid this full stop. Thanks Bovine
(comments are locked)
|

From what I read and been told, calling GC.Collect() yourself is a bad idea as it 'breaks' the Garbage Collector's predictions and estimations, which are pretty autonomous. Unless you had GC problem to start with, you should leave it alone. And if you're having problem with GC, you might be attributing too many new objects, perhaps the project could use optimization?
I was reading this area of the docs:
http://unity3d.com/support/documentation/Manual/iphone-Optimizing-Scripts.html
But I think I misunderstood. Where the heap is small, so 200K, then it is 'cheap' to call Collect. But my heap is more like 3.5MB which is not so small and I think hence the 60MS.
I am going to try the suggestion of forcing a larger heap size as this will allow me to call Collect() between levels/when static screens are displayed and reduce the frequency of collects, but I am mindful of the fact that it will be all the more painful when it does kick in...
There are now NO new objects allocated in the script code besides return values from Coroutines and I've no idea how expensive these are. (i.e. yield return new WaitForSeconds()). I could consider using a different strategy, a reusable equivalent for WaitForSeconds() that checks whether it needs to be called, but this isn't as cheap as never being called. Still if returning new objects is the cause, then I may try that as it's a direct swap out and means the return value can be re-used and not allocated each time - why isn't there already one that works this way please?
The main culprit was naive string concatenation which was eating around 80K per second, but I cannot find anywhere else I am doing any of this. Still it's down to 3K per second but with a small heap I'm going to judder every few minutes. It may be acceptable....
Thanks Bovine
It's worth noting that the practise of calling the garbage collector was one recommended in a Unity doc, possibly the one linked, though that seems to be broken now. My understanding is that the garbage collector under Unity (probably just under mono) behaves quite differently and so doing GC when say, showing a meny and pausing the game, is quite safe.