Game terminates due to poor memory management
Product: Star Wars: Galaxy of Heroes
Platform:Apple iPhone
What type of device are you experiencing the issue with? iPhone 12 Pro Max
OS Version iOS 14.5
Ally Code: (Find it here: http://bit.ly/AllyCode ) 622-343-643
What type of issue do you have? Other
How often does the bug occur? Rarely (0% - 9%)
Summarize your bug Abnormal exit of application (Jetsam events). This happens when trying to enter a new battle. I have Jetsam logs that show this and the fact that Apple iOS has chosen your app to terminate means you are really doing very bad things with memory management.
Steps: How can we find the bug ourselves? Use any iOS device and create an environment in which memory would be stressed. So open up a lot of applications and then try and just enter new battles. This is by no means a guaranteed method to cause the problem but might make it easier.
Connection Type Mobile
Please select your region North America
Country United States
Product: Star Wars: Galaxy of Heroes
Platform:Apple iPhone
What type of device are you experiencing the issue with? iPhone 12 Pro Max
OS Version iOS 14.5
Ally Code: (Find it here: http://bit.ly/AllyCode ) 622-343-643
What type of issue do you have? Other
How often does the bug occur? Rarely (0% - 9%)
Summarize your bug Abnormal exit of application (Jetsam events). This happens when trying to enter a new battle. I have Jetsam logs that show this and the fact that Apple iOS has chosen your app to terminate means you are really doing very bad things with memory management.
Steps: How can we find the bug ourselves? Use any iOS device and create an environment in which memory would be stressed. So open up a lot of applications and then try and just enter new battles. This is by no means a guaranteed method to cause the problem but might make it easier.
Connection Type Mobile
Please select your region North America
Country United States
Your developers should watch this:
https://developer.apple.com/videos/play/wwdc2020/10078/
Also the video above suggests that you might be able to code in some recovery options should your application receive a Jetsam event, all ios apps should expect to be terminated by jetsam at some point but usually that occurs when you are suspended. In your case the application was shut down because it went over max memory that the OS imposes on apps. Still the video above suggests that you can clean-up when it occurs. For example in GAC I entered a battle and crashed. I lost those characters for the war and the battle count went to 1. A proper clean-up would have detected the abnormal termination and not counted the battle.
If you can just code it proper recovery techniques I wouldn't even care that it got terminated.
I have attached the JetSam .ips file that goes along with the crash seen in this video. I had to rename the file to make it attach. Here is the important part:
{
"uuid" : "7d62f508-86cf-3eec-8b5f-7db3d1cf7400",
"states" : [
"frontmost"
],
"lifetimeMax" : 183488,
"killDelta" : 2702,
"age" : 1612948810758,
"purgeable" : 8,
"fds" : 200,
"genCount" : 0,
"coalition" : 2202,
"rpages" : 183488,
"priority" : 10,
"reason" : "per-process-limit",
"physicalPages" : {
"internal" : [
67267,
111314
]
},
"pid" : 17636,
"idleDelta" : 2674299347,
"name" : "bv",
"cpuTime" : 3493.0441700000001
},
And the reason has a meaning of:
per-process-limit: The process crossed the resident memory limit imposed by the system on all apps. Crossing this limit makes the process eligible for termination. If the process is an app extension from your app, note that extensions have a much lower per-process memory limit than foreground apps. Carefully consider your needs before using technologies with a high-baseline memory cost, such as SpriteKit or a MKMapView, in an extension point. Alternate solutions may be more appropriate. For example, an image created by MKMapSnapshotter has lower memory use than a MKMapView, and is a better choice for many extension-point scenarios.
I have no idea if you know the details of why their is an increase in crashes, their is a post that admits that you have seen it but you incorrectly label them as crashes. It's not really a crash, it is a forceful termination by the iOS because of poor memory management.
Jetsam monitors memory use and kills applications which are not good memory citizens. A good memory citizen is an application which is willing to give back memory when asked and does not keep asking for more memory.
In order to be a good memory citizen and not be killed by Jetsam, an application should use the following techniques:
- Lazy initializers on any objects which may require substantial memory and which can be easily recreated.
- NSCache combined with NSPurgeableData for any large memory resources which come from an external source our require substantial CPU cycles to recreate. This is particularly useful for things like processed avatars images loaded from the web or a database. For example, if you have CollectionView cells which use individual images for each cell and those images have something like a circular mask, you can cache the image for reuse and empty the cache when memory is needed. This will speed up your app performance and allow it to be a good citizen by returning memory when requested.
- Streaming of file data which needs to be processed rather than loading all the data into memory. If the app needs to process a large file to extract information, using memory mapped access to the file can vastly reduce the memory footprint and keep your your from ballooning which would trigger Jetsam.
- In the ViewController's viewDidDisappear, nil out any resources which can be easily recreated in viewWillAppear. This important to minimize your background footprint if your app runs in the background. The same goes for the AppDelegate method applicationDidEnterBackground:
- Monitor the ApplicationDelegate method applicationDidReceiveMemoryWarning:, and the ViewController method didReceiveMemoryWarning in order to release the re-creatable resources outlined above.
- Use the profile Allocations tool with reference counting on to check that you don't have reference cycles which are preventing resources from being released.
- In test/debug mode, you can have your app call the memoryWarning methods itself and see if the memory is being released.
One important note about Jetsam, it seems to be very important that an app be willing to give up some memory. This as important if not more important than the absolute amount of memory used. So whether your app uses 50MB or 150MB, it needs to be able to give some memory back when asked in order to avoid being killed by Jetsam.