I am currently working on an app that runs on iOS and Android. The core of the app is written in C++ and allocates over time more and more memory. The thing is I want at the same time to be able to use as much memory as possible and ensure the stability of the app.
Of course, to do that I would need to know how much memory I can still use. This way, if I see after a while that I am going to need more than it is available, I could stop allocating instead of getting killed by the OS or crashing.
The problem is, after reading and trying different solutions, my feeling is the information that you dynamically get is not reliable enough. For instance, on iOS:
[NSProcessInfo processInfo].physicalMemory
This is one of the typical examples / answers I have read that seems not to be reliable. It seems that you cannot get enough information dynamically to make sure that you still have enough memory, because the OS will at some point kill your app if it uses too much memory and sends warnings before. But it also can kill other apps in between, so stopping when I receive the first one seems not to be an optimal solution.
After reading a lot of posts, I am a bit confused on the topic. Is there a way to know dynamically and reliably how much memory is left for my app on iOS/Android ? Or memory management from these OS is too unpredictable for that ?
Thanks for the help !
By design, you're prohibited by the operating system from ever using up all the physical memory on the device; what's more, the requirements of the operating system and the other apps running on it mean that the amount of memory your app can comfortably use will vary over time.
Therefore asking how much memory you have left to use isn't really sensible. You should design your app to use as little memory as possible, and then optimize until you use less than that.
Be aggressive about caching things out to disk.
Listen to the OS-provided notifications that your memory is under pressure.
Design your app in such a way that you can restore its last UI state from fresh launch: app launches and task switches are presented to the user the same way, and they won't and shouldn't need to know the difference.
If you do use more and more memory, the OS will try and terminate other apps to make room for yours. That means, bye bye Facebook, bye bye Twitter, bye bye Mail, bye bye Contacts. Your users will notice, and they will choose to launch your app less often, or review it less favorably, as a result.
Related
There are a lot of questions on here about "My app drains battery! Why?". That is not what I am looking for. I am wondering about how to create an app which can get which apps are draining the most battery.
I know it's possible, because I've seen apps that can do this.
I think you could work it out by CPU usage:
Take a look at this answer:
CPU usage per application in android
I suspect you would need to continually run a command like this and parse the results into a database, combining previous results to work out a running tally.
I am getting a message like "your application restarted 9 times in 5 minutes()", when I tried to clean Junk Files using "Clean Master" application.
Please find the screenshot for this issue. I am not able to figure out why this message is coming. Any idea on this???
These apps may have once been useful but the Android has progressed far enough that they are now outdated, unnecessary and rather harmful.
On Windows, you want to keep as much RAM as possible as you can so that programs have enough room to operate. When RAM fills up, Windows is forced to start using hard drive space as virtual RAM and hard drives are much slower than physical RAM.
This is not true for Android.
Android’s operating system has its own native handler for assigning RAM to apps and making sure that all of it is being used in the most optimal way. In fact, Android purposely tries to keep apps loaded into RAM for better performance. RAM is fast, remember? On mobile devices, every bit of speed is critical for a good user experience, so keeping apps in RAM is actually a good thing.
Not only does Android handle RAM assignment, but it also keeps track of background apps so they don’t use up unnecessary processor resources. There’s no noticeable performance hit for leaving apps loaded in RAM.
App killers, memory boosters, performance enhancers, etc all claim wiping memory will speed up the phone. With current versions of Android, that's simply not true. It's actually the opposite. What will happen is the task killer app kills other apps which use resources to process. Then the OS restarts those, or other apps to fill the memory again, which takes even more resources. The task killer app kills again and the process repeats over and over. So in reality, those kinds of apps reduce performance and increase battery usage by restarting apps again and again. Remember, those dormant apps don't consume any additional battery or CPU in the first place.
I know that Android may kill applications e.g. if it's low on memory. In a comment to another question a user stated that if my app would require less memory, it would be less likely to be killed. I wonder: is this true? Where is such a behavior documented? Which other factors influence the likelihood of being killed?
is this true?
Perhaps.
Where is such a behavior documented?
It's not, which is why the answer to the previous question is "perhaps". The only way to determine the behavior would be to examine the Android source code, and that would only be relevant for Android devices built using that same source code. Not only can Google change the algorithm over time, but device manufacturers and ROM modders can change the algorithm as well.
Which other factors influence the likelihood of being killed?
The primary determinant is what is in the process, as is described in the documentation. So, a process with a running activity will be less likely to be terminated than a process with no running components at all.
Nothing else is formally documented. My understanding is that process age is a factor, so that apps with a service do not live forever, but I don't recall that this is mentioned in the docs.
Also, bear in mind that the user can get rid of your process whenever the user wants, via the recent-tasks list on 4.0+, or via a third-party task manager, or via Settings. Hence, you should make few assumptions about the longevity of your process.
I am writing an app to evaluate the feasibility of a Bluetooth P2P network on Android.
I noticed that on a Galaxy Nexus, it uses very little battery, while on a Nexus S, it drains the battery very quickly. This is directly caused by high CPU load due to Bluetooth.
Now, I would like to collect information about how much battery drain my app causes on the devices it is installed upon. Simply logging time vs. battery level is useless since I don't know when the device is in use, and even if I logged that, I would not know if the user is playing 3D games while Torrenting over WiFi or reading an eBook on a dimmed screen.
To make the problem worse, not all battery usage caused by my app is attributed to it in the battery screen - some is listed as "Bluetooth", for example (again, device-dependent).
Is there any easy, privacy-preserving way to get useful information on non-rooted devices? The devices are not under my control. I cannot simply go look in the menu, I cannot use ADB.
The Android API doesn't support this currently. The only available documentation is the one describing how to use BatteryManager's broadcasts, which only supply the overall battery level and no per-application details.
I suppose that even if there are undocumented ways to emulate what the System Settings battery manager shows, they would require rooting.
AFAIK there is no way to do this. The closest you can get to doing this is to hook up the device to a monitoring tool like little eye labs which does draw the battery consumed by your app over time on a graph. It also supports marking key events in the app's lifetime like turning on WIFI / bluetooth etc.
There is no support for doing this remotely, but you can get the data on your own test devices.
This approach is quite crude, but it may help. You can use the existing BatteryManager broadcasts to track changes to the overall battery level while your app is active.
Knowing when your app is active is a separate issue. If your app consists entirely of Activities, then you can get good results by starting to track whenever any of your Activities' onResume() methods is called, and stopping tracking in onPause(). If you can have all your Activities derive from a single base Activity class, then this is quite easy. See How to detect when an Android app goes to the background and come back to the foreground for suggestions on how to track this.
If your app is more complex, and the smart stuff happens in a longer-running component like a Service, then it's much harder.
This is crude, but at least it would help you distinguish "playing 3D games" from "using my app".
I have an app which is closing after some period of time. The app is consuming around 20MB of RAM. I do have more than 120MB ram still available. I am not sure if this is the OS behavior or some problem with my app. Even with app like Opera mini, after a while it restarts again. Is there a way to avoid this problem?
Problem with my app: I need to search the SD card for files with some specific extensions like mp3, jpg and some others and store it in local variables. When the app restarts again, it needs to do that work again. I need to avoid that. There are some app level settings which I am taking care using sharedPreferences. But the huge data is the problem.
Thx!
Rahul.
This is perfectly normal behavior. Android will terminate processes after a period of time running in the background. Generally speaking, there is no "problem" for most well-written apps, that save user data to persistent storage (files, database, SharedPreferences) as activities get stopped, etc.
If you feel that you have a process that should live longer, please edit your question to provide a justification for this claim, as that may help us to provide recommendations on how to organize your app.