I am currently struggling with memory management inside a webgl application on the web, on iOS only.
I keep getting the following error message :
Application 'UIKitApplication:com.apple.Preferences[0xa7c1]' was killed by jetsam.
I understand that Jetsam is the system process responsible for memory management, but the crash occurs while the browser uses around 25% of the device's RAM, which is not that high. I don't have any other open application while running my webGL content. What I don't understand is what Taun Chapman said :
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.
Well, the app needs more memory in a short time (when unzipping 3D models using workers), I can't continue my app without it! And it crashed at these particular times.
Moreover, I think I have some memory leaks in my app, according to Chrome DevTools I am currently trying to fix. But the browser itself seems to have some leaks too. Thus, fixing mine will just delay the inevitable.
I know the following question is odd, or inappropriate, but do you know if the jetsam "limit" can be increased ? Or if you can add an exception on the currently running WebGL app ?
For your information, I use the Three.js WebGL library and the zip.js library to compress my 3D models.
Yes, I've already read the following question : Why does simple website crash on mobile (iOS Safari and Chrome, at least)?, but the problem does not come from my CSS.
The 10.3.2 version of iOS (released the 15th of May) made Jetsam less aggressive, or at least, the memory is better handled.
https://support.apple.com/en-gb/HT207798
Related
I recently profiled my app using Xcode VM tracker instrument.I found that app has lot of dirty memory especially performance tool data. So i want to know what are the reasons of the huge dirty memory and performance tool data.
Any help would be appreciated.
Your app takes 51MB to store, when it is suspended. The performance tool itself adds an overhead of 30MB. Which leaves 20MB for your app.
From the listed items, it looks like your app is graphics heavy. In fact, it looks very similar to this post. Which makes me wonder if these objects are still processing or waiting to be released, when the app is suspended.
Alternatively, I wonder if you could free a lot of those animations and images when entering background, and reconstruct them when entering foreground.
Finally, note that Apple recommends removing strong references to images, data from disk and media to reduce dirty memory.
Since I just had the same problem, here is what I found:
The "Performance tool data" entries were from libBacktraceRecording.dylib.
You can disable backtrace recording in the scheme editor.
See the related question Memory leak with “libBacktraceRecording.dylib” in React Native ios application.
All over this document Apple mention iOS terminates apps under certain conditions, and the most popular reason seems to be freeing up some RAM. And that causes issues for apps that do not implement state restoration - some of the content user is working on and stepped away from for a moment could be easily erased. There's even a 16 page thread on Apple forums where users complaining about that.
Is anyone aware why iOS actually terminates apps instead of moving memory occupied by them onto disc/swap?
Does termination actually provide considerable performance improvement compared to other means?
What you are describing is paging, or more accurately, page swapping. The iOS version of BSD Unix does not perform paging, for lots of reasons. Here are a few educated guesses:
It's too power-hungry for a mobile device.
Flash memory can't handle the churn involved in paging. Flash memory has a limited number of lifetime write cycles per storage location, and paging would chew through the life of the flash chip.
As the other poster pointed out, swapping to disk would use up available disk space, which is also limited. Not a problem when you have a 500 GB drive, but it is a big problem on a device with only 16 GB of HD and 1 GB of RAM.
You're not going to get an answer for this question here. Apple don't explain the inner workings of iOS and anything else is going to be guesswork.
Here's my guesswork:
iOS is a heavily resource constrained environment. Memory is limited but so is disk space - a 16GB iPhone has 1GB of RAM, so "swapping to disk" isn't really something that can be freely applied. When do you stop? How do you know this isn't already being done, but there is only a limited swap in place?
The primary goal of iOS has always been to prioritise responsiveness of the foreground app. Anything other than warning, then closing background apps would probably impact this too much. If there are 15 apps in the background then imagine the processor load on nicely swapping the memory out for each process?
Because the RAM that was saved onto the disc would be much slower. It's better to cut the program then having it run poorly. I think that answered both questions.
Thanks everybody for responses. I had to do some research to answer this question, though. So I was looking for more understanding that led into "app termination" decisions. I know, there are some smart people working in Apple, but for me it always help to understand the reason something is build "this way" rather then just following it.
It turned down into these 2 questions
Why iOS terminates apps instead of freeing memory by paging out (swapping)?
Does termination provide considerable performance win?
To understand that I dug a bit into the history of iPhone. There's a video that was accessible on iTunes, unfortunately the link does not work anymore. Anyways, the video was introducing the very first version of multitasking on iPhone 3G (or was it 3GS? Not sure which device starts to support multitasking).
Nowadays iPhone devices are quite advanced in terms of hardware. Those are actually more advanced then some desktops we had 7-10 years ago, which already have had incorporated swapping long ago. But if we look for first iPhone releases, those are not that much advanced in terms of hardware. iPhone 3G is 620 Mhz ARM and 128 RAM. iPod touch 1gen had 400mhz ARM. And multitasking was supposed to run on all the devices of that time.
If we take a look at iOS, it was always has the smoothness of animations in priority; taking look at hardware I see it would be challenging to have both snappy and responsive device along with processing swapping background applications memory, so it seems very logical and very fair to terminate apps. A year or two later Apple provided APIs to facilitate implementation state restoration.
But if we look at the current iPhones and iPads - they do have enough power in order not to terminate apps and just drop their memory on disk without any drop downs in animations and foreground app performance. Why not add that on latest devices? I assume this is common for the software industry; new features often prioritised higher then improvements on existing workflows; Apple has been releasing MobileMe, support for Retina displays, AutoLayout, iCloud - so I can understand that cool improvements of already existing features has been sacrificed.
The issue with apps that don't provide state restoration is easily solved by providing state restoration.
Just killing apps when the system runs out of memory is a huge performance gain. Consider that the system usually runs out of memory when you launch another app, and any action that is done instead of killing old apps would have to be done before launching the new app; that's about the most performance critical point in time.
And for at least five years you have been told that when your app goes to the background, you should store just enough state to come back to that state if your app is restarted.
I have started receiving app termination due to memory pressures very recently (mostly with iOS 7). The app used to work very well on iOS 6.
The app is mostly uses a UIWebView to display a webpage. However for a few webpages it creates ever increasing Dirty memory with most of it due to Image IO and Performance tool data (see attached instruments screenshots). I am completely clueless as to where to dig next. Could someone guide me what should I do here onwards? In the second screenshot I see a sudden bump in the memory allocations. Is there a way to spot the process/part of the code which caused it?
EDIT One can reproduce these results in a simple demo kept at www.github.com/nikhiljjoshi/iosCrash (just change the site to www.nzz.ch).
Thanks in advance,
Nikhil
I am working on an iOS app in Xcode. Earlier I got it to start and run, up to a limited level of functionality. Then there were compilation failures claiming untouched boilerplate generated code had syntax errors. Copying the source code into a new project gets a different problem.
Right now, I can compile and start running, but it states before even the launch image shows up that the application was closed due to memory pressure. The total visual assets is around 272M, which could be optimized some without hurting graphical richness, and is so far the only area of the program expected to be large. (The assets may or may not be kept in memory; for instance every current loading image is populated and my code never accesses any loading image programmatically.) And it crashes before the loading image has itself loaded.
How can I address this memory issue? I may be able to slim down the way images are handled, but I suspect there is another root cause. Or is this excessive memory consumption?
Thanks,
Review the Performance Tuning section of Apple's iOS Programming documentation. Use Apple's Instruments application to determine how, when, and how much memory your app is using.
One approach you should consider is to disconnect the graphics resources from your application, and add them back one-by-one once you feel they meet the requirements and limitations of iOS.
Now, this part of my answer is opinion: it sounds like your app is a high risk for being rejected from the App Store, in case that is your intended destination for this app.
I am working on an iOS app in Xcode. Earlier I got it to start and run, up to a limited level of functionality. Then there were compilation failures claiming untouched boilerplate generated code had syntax errors. Copying the source code into a new project gets a different problem.
Right now, I can compile and start running, but it states before even the launch image shows up that the application was closed due to memory pressure. The total visual assets is around 272M, which could be optimized some without hurting graphical richness, and is so far the only area of the program expected to be large. (The assets may or may not be kept in memory; for instance every current loading image is populated and my code never accesses any loading image programmatically.) And it crashes before the loading image has itself loaded.
How can I address this memory issue? I may be able to slim down the way images are handled, but I suspect there is another root cause. Or is this excessive memory consumption?
Thanks,
Review the Performance Tuning section of Apple's iOS Programming documentation. Use Apple's Instruments application to determine how, when, and how much memory your app is using.
One approach you should consider is to disconnect the graphics resources from your application, and add them back one-by-one once you feel they meet the requirements and limitations of iOS.
Now, this part of my answer is opinion: it sounds like your app is a high risk for being rejected from the App Store, in case that is your intended destination for this app.