Zombieville USA - performance hitches

So I’ve released my app, Zombieville USA, on the app store and its doing fairly well so far and getting good reviews, but there’s this periodic framerate hitch that I’ve been trying to track down ever since submission.

The Problem: Basically every few minutes or so, the game will stall briefly (sometimes the stall will last for a fraction of a second, sometimes for a full second or two). Both the visuals and the sound will freeze during this time (especially noticable if there’s a sound effect playing at the same time - it will hang in the middle of playback in a most noticeable way). This stall is then followed by a 5-6 second period of decreased performance overall - the framerate is lowered, and the responsiveness of the touchscreen goes to hell, almost like its recovering from something. In a fast paced action game like mine, this is really annoying, since during this period of decreased performance, the fire button becomes unresponsive. Freshly restarting my test device seems to reduce the intensity/frequency of these stalls and their following period of poor performance, but they always occur eventually.

But wait, there’s more! I first discovered and reported this issue a while back, here’s a link to that thread.

http://forum.unity3d.com/viewtopic.php?p=120927&highlight=#120927

For some strange reason, my game was experiencing this same stall every 15 seconds or so after I added a ‘menu’ level to my project, rather than every few minutes. I ultimately removed the menu level, and simply incorporated its contents into my main game level, which solved the extremely high frequency of the stalls.

So what’s up with my game? These stalls occur regardless of what’s going on on screen - it can be in the thick of battle with a dozen zombies, or just walking down the street with only one enemy on screen. I suspected garbage collection was the source of these issues, so I tried putting a request to run GC at the start of each stage. This seems to have had little or no effect. I also completely re-wrote my zombie spawning system to use a pool of recycled zombies that are always in memory, but hidden off screen until they’re needed, rather than constantly instantiating and destroying them. This helped performance in general, but did not remove the stalls. Overall the game runs pretty well, but this issue is driving me crazy, and seems completely random and out of my control.

I’m going to try sending in a bug report with my project so the Unity folks can pick it apart.

I don’t really have a solution for you, but I do want to say that our game Sheepstacker suffers from the same thing. Every few minutes, we get some pretty bad hitches. The sheep are all pooled (just like your zombies), so there’s not really any real-time instantiation going on.

I believe in our instance, it’s definitely garbage collection. On level load, I’m requesting that garbage collection be performed, but I don’t really think it’s helping. But looking at the printout from the profiler, it looks like the heap is getting freed up right when the framerate hitches occur.

I had this happen with Downhill Bowling sometimes as well. Maybe it’s something to do with Unity? Perhaps a bug that still needs to be fixed? Other than that, I have no idea for these weird stalls.
-Blayke :slight_smile:

Could you search for a “WARNING → applicationDidReceiveMemoryWarning()” text in the xCode console or put a breakpoint in applicationDidReceiveMemoryWarning function in AppController.mm

Could you post stats from you console “around” the spike time?

Next thing to do would be running game with instruments (Activity Monitor/Leak/Object Allocation s tools) to see how much memory your game is using or if there is any suspicious activity on other processes.

this error is caused because of the garbage collector that cleans memory when you are in the middle of the game, I sent a feature request some weeks ago in order to have a function that forces the garbace collector to collect when I want but the only one thing I received as a reply was “could you be more specific” and closed my ticket. (Someone who has knowledge about programming would understand I think).

I recommed not to use ArrayList because this causes a constant 4K increase in memory use and not to instantiate objects every moment.
When your game begins, create 5 or 10 zombies and put them in a fixed array, cyclically use each monster

I wouldn’t be so sure in this specific case. Garbage collectors loop generally takes much less time than 1-2 seconds and you should be allocating tons to get collection every 15 seconds (I never seen that before on iPhone).

You can “disable” garbage collector by not allocating objects (I know it can be a tough challenge) - there are number of do’s and dont’s in C# to achieve it.

I am already doing this, as described in my original post. Using a pool of enemies in a built-in array vs. instantiating/destroying them had no effect on these stutters. I am using javascript arrays to handle my particle system though, and frequently using .Push() and .RemoveAt() - if that’s leading to rapid memory consumption I’ll revisit that code and have it use built-in arrays instead.

As for ReJ’s questions - the stats readout during these spikes aren’t very telling. The cpu-player max time spikes up to a huge amount, but nothing else exhibits any unusual behavior.

I’ll do some tests tonight and look for “WARNING → applicationDidReceiveMemoryWarning().” This all rings of a memory issue, and I’ve gotten reports of crashing from players using jailbroken phones… and those players were able to resolve the crashes by disabling some of their memory hogging mods/software.

If I am riding the edge of how much memory I have available, what is the best way to reduce it? Would reducing the size of my assets be the major factor, or is it more likely to do with my scripts? A lot of my textures are pretty high-res, I have some 512x512 ones for UI, background art, etc. Are variables that contain references to other gameObjects, textures, etc. costly as well? There are a lot of holes in my understanding of memory usage in Unity, what’s expensive vs. what is negligible or ‘free’.

Textures will be the major factor. Make sure your textures are PVRTC compressed and resolution is not higher than actually needed.

Most probably next is audio followed by animations.

Variables on the other hand are tiny. Once you’re done with assets optimization, you could take an extra effort to minimize amount of object allocation in your scripts - that will decrease your Garbage Collected heap - in the best case it could be possible to save around 2-3Mb there.

Thanks for the info ReJ, that helps clarify things. I’m probably strangling the poor iPhone with my hi-res sprites, since I’ve been very reluctant to use PVRTC compression. With textures on 3d models it isn’t as noticeable, but when you’re using a crisp, hand drawn art style like mine it really destroys the visuals with ugly artifacts. I’ll take another pass at my textures though and make sure none of them are larger than they need to be, and see where I can use PVRTC without being highly noticeable.

My sound effects are minimal and very compressed, my music is an mp3 which could probably be compressed further.

Remember that the iPhone resolution is only so large, and you never get any closer to your artwork than the plane the action resides on…

…since there are only so many pixels, there’s isn’t a need for FULL SCREEN texture to ever be above 480x320, let along a single element that is merely a portion of the the screen; you can’t draw more than the pixels that are already there.

I know this all goes without saying perhaps, but then again you ARE using 512’s. :smile:

Just because a texture is 512x512 doesn’t mean you’re seeing it all at once, or even on one contiguous object.

For instance, I have a ‘store’ in my game that uses 16 different icons, only 5 of which are displayed at any given time, but all 15 icons, their price tags, and the building graphic that surrounds them share a single texture.

If it’s an atlas fine…hell I’d use the entire 1024x then…

…either way I misunderstood what you were using them for. :slight_smile:

i thought vram didnt count toward your mem footprint?

I’m pretty sure the iPhone has no dedicated VRAM, so textures would have to draw from the same limited memory that everything else is.

I agree that uncompressed images are likely the issue. I’d copy off a test project and compress all the images, than see if the freeze-ups disappear.

Any time I’ve tried to use relatively large uncompressed images on the iphone, I’ve had crashing problems or freeze issues.

I could see the garbage collector firing constantly in an effort to free up memory in those constrained conditions. Even with pooling, we do not know what memory is being allocated behind the scenes by the UnityEngine. In my experiences with java’s VM, if memory usage is close to its max allocation, it will churn trying to free what little objects it can.

An uncompressed 1024x1024 texture is about 6MB of graphics RAM, which is 25% of what you have at best to use for your graphics.
So thats definitely a no go

For those who are curious, my texture sizes turned out to be irrelevant, but it definitely seems to be something memory related. I ran some tests with activity monitor, and my app’s memory usage very quickly swells during play, even after all assets are in memory. It even increases while the game is paused and nothing is really happening… eventually the memory usage hits a plateau, and that’s when the stall occurs. The stall and the memory growth stopping always coincide, but its not a specific ceiling. I tried compressing the crap out of my textures, and that simply made the stall occur 10mb’s earlier. It didn’t matter if my app was using 30, 40 or 50mb, the first stall happened like clockwork within a couple minutes of starting a game.

I’ve submitted my project for dissection, hopefully its just something stupid that I’m doing. :slight_smile:

Sometimes it’s not so clear because the os can cache memory and release it back to the app when it requests it, so it isn’t unity or possibly even your app related.
Like for instance in a game I have I use nsfilemanager a lot and I’m always running with @ 3 mb to spare and when I drop below the level to trigger mem cleanup (3 or 2mb I think) I’ll mysteriously bounce back up and have more memory. It doesn’t mean my app is to blame. It my case the men was released long ago but the mem was never returned to my app till it needed it.

Doesn’t mean this applies to you for this issue, but it’s good to keep in mind.

Dissection by whom, may I ask?

Yep! All the same RAM. Textures, program, background processes, OS, sound files - all figting for the same RAM.

At the Apple road show tour they preached an approx max memory footprint of a running app at max 25-30 MB. Anything above that and you into the danger zone for getting memory related problems and eventually forcibly shutdown by the OS watchdogs