Why does iOS kill my app on launch for memory usage when it's not using that much?

I’ve done just about all the homework I can on this, so am now seeking some sage advice from the forum.

The initial version of our little game worked great on our test devices, including the oldest iPhone/iPad we are supporting and had access to (iPhone 6s, iPad 4 mini). However, once we had a few people using it in the wild, we were getting crash reports (only from iOS), all of them memory related. We were, indeed, not being very smart about memory usage.

I was able to get the game from almost a gig of ram to right around 230MB, but it still behaves the same, and it’s reproducible. If I load up a test device with other apps running in the background, many using more than my app, to the point where there’s not enough ram left for my game, and then start my game my app gets killed even though (a) it’s in the foreground (b) it’s using less memory than at least a few apps running in the background.

So that’s my question: Why does my app, that’s only using 230MB (which seems pretty low for a game (?)) and running in the foreground get killed when Words With Friends is sitting in the background using more than that?

I’ve stumbled across the concept of “memory pressure” and found this page that’s unsurprisingly nonspecific: Responding to memory warnings | Apple Developer Documentation

But I guess I’m trying to understand if I’m doing something unexpected/wrong. There’s really not much in the game to release when I get the warning, as it’s on launch. I’ve gone through the memory with a fine-tooth comb, rewritten some shaders to be more processing heavy than memory heavy, compressed all the things, etc. so things are already pretty trim. There’s more I could do to reduce the footprint by a few MB, but I worry I still wouldn’t hit whatever magic number iOS is okay with. Especially considering the green part of the memory meter in xcode goes up to 1GB! Is this (specifically: getting terminated on launch for loading and initial set of assets) something that all unity iOS developers deal with?

Aside from any general advice, I’d love to confirm whether you all are actually fitting your games in less than 230MB or if there are ways to appease the iOS memory gods in such a way that you can use more than that without getting terminate.

Surely I don’t have to stagger load assets, making my game load slower, and increasing download size, just to trick iOS into not killing my app, by increasing my memory usage more slowly …

Anyone else dealing with this? Any pointers?

Thanks!

After a week of my best QA engineer (my mom) closing all the apps on her iPad before starting the game, we don’t have any crashes, so it seems like maybe it’s fine as long as there’s already enough ram available before the game starts.

This seems like something that wouldn’t be unique to my game, but I can’t find anything that seems to address the case where you’ve already trimmed your memory footprint and aren’t leaking memory, but the device doesn’t let the app allocation initial assets because of other apps in the background using up all the memory.

Not sure if this thread is quiet because literally everyone solves this and the solution is well known, or if I’ve managed to stumble across an edge case. Hopefully someone has a direction for me to explore in.

Thanks!

Edit: Should mention that we’re on 2019.4.0

I never experienced this, and don’t know any solution. To test the issue you described, I launched every single app installed on my iPad, including video player, Safari, maps, etc., and then launched my own game on top. All apps remained in memory and my game worked fine. That was iPad 2017 with 2 GB of RAM.

Thank you for the reply!

I … I do have an embarrassing discovery that your post lead me to:

I’d done the test you mention before and my game would crash. After a moment I’d try again and it would work, because enough memory had been cleared out. This behavior was repeatable.

I repeated the test just now and and while I was digging around, I remembered/realized that I was throwing an exception in my Application.lowMemory handler. I had been assuming that, like in MonoBehaviors, Unity would just catch the exception and log it so I could see it in the developer tools online. I took out the exception and repeated the test and … it didn’t crash :sweat_smile:

Seems like I was sadly, sadly mistaken about Unity catching exceptions for me in that callback. I think I’ve been killing my own game!

I can’t seem to find any verification in the documentation that states that Unity will catch exceptions from MonoBehaviors but not Application event handlers. I’ll keep looking, but if anyone has an insight about that. it would be appreciated.

Thank you, Ukounu, for taking the time to run the test and a nudge in a productive direction!

2 Likes