I created an application that creates a background service. When I close the application the service is running and when I go back to get it back to "bind" (bindService) to it for communications.
The problem is that when I close the application and re-enter, it significantly increases the memory in use. Spend 20Mb -> 24Mb, if I go out and come 24Mb -> 28Mb, 28Mb -> 30Mb ... Thus breaking up the application. I have no bitmaps. That if enough use static arrays but I've tested and are not the source of the problem.
When I close the application completely (including service) call System.exit(0) and clean all the memory, but of course, I can call when I leave the service running as it closes. I tried to call the Garbage Collector (System.gc()) and if I notice that memory decreases to close, but when you open the application again same memory increases.
I would greatly appreciate the help, Bye!
Considering information we have, I suspect the problem is an Activity leak.
Can you please check 2 things:
Check carefully do you use Activity Context (reference to Activity) that can be stored? Particularly in Service.
Try to make an experiment - select "Do not keep activities" in Developer setting - will the memory be decreasing after each Activity launch?
Related
1) Activity is on onStop() state.
Example: overview button tapped.
2) Working with phone till android pushed out app from memory.
Example: gaming
3) Overview tapped and app tapped then crash
Any solution to destroy it when pushed out from memory?
There is no assurance that onDestroy will ever be called. Do not depend on it, it should be used for opportunistic cleanup only. Especially in the case of a crash, it will NOT be called, because the app may not be in a state where its safe to do so.
You can do a couple things. Manage your absolute necessary clean up in the Application file. (low memory) callback can call the same method.
One idea would be to have a baseclass or abstract model where you keep a reference to the the active version in Application class. Then if low memory is called, you can manually call your (selectedActivity.OnDestroy).
It's a work around to make sure that a low memory calls your cleanup. You can also add one for unhandledException listener to make sure a crash can call your cleanup as well. Depends on how important your final cleanup is in the event of app closure.
If the cleanup is too heavy or time intensive, you can simply set a "bad closure" flag in a DB or shared pref that you check on startup and do your cleanup on the next app launch.
Can anybody confirm the following regarding the android application lifecycle?
1) When application is in foreground the memory will contain instance of the Application object, instances of all activities (not killed) and all the object references that are referenced from one of the root's (haven't been garbage collected)
2) When application goes to background, at some point the Android Framework can:
a) Kill the whole process given to the purpose of the application which will essentialy erase all the objects from the memory
b) Kill ONLY (so essentialy no other object reference will be deleted) the activities (by finishing them and in essence any fragments as well) saving their states and creating the Activities Stack and leaving anything else (Application object, any other static objects, references that are reachable from any of the roots).
I'm mostly interested in 2b, but I would appriciate confirmation on all of these points as I'm trying to grasp mentaly the whole concept from start to finish.
If you are looking for official confirmation then better ask Google only :).
but i feel after reading this you will get a better understanding of these concept.
Android memory management
android process lifecycle
Answer for 1st question:
yes confirm using DDMS.
answer for 2a question: yes OS can kill process any point of time when needed memory for other process which will result into killing all object related to process.
answer for 2b questiong:
From official documentation
Process Lifecycle 3. A background activity (an activity that is not visible to the user and has been paused) is no longer critical, so the system may safely kill its process to reclaim memory for other foreground or visible processes. If its process needs to be killed, when the user navigates back to the activity (making it visible on the screen again), its onCreate(Bundle) method will be called with the savedInstanceState it had previously supplied in onSaveInstanceState(Bundle) so that it can restart itself in the same state as the user last left it.
Yes you are mostly correct about 2b).
If an activity is paused or stopped, the system can drop the activity
from memory by either asking it to finish, or simply killing its
process.
However there are instances where onSaveInstantSate isn't called:
Note that it is important to save persistent data in onPause() instead
of onSaveInstanceState(Bundle) because the latter is not part of the
lifecycle callbacks, so will not be called in every situation as
described in its documentation.
Android Docs Source
You can request android to always destroy activities on background by enabling the following developer option. If you are debugging your app you should be able to step through the life cycle methods and see what is happening.
Settings -> Developer options -> Apps -> Don't keep activities
There is no typical life-cycle for application exists. Application object lives in memory until it is not being killed either by Android itself or by manually by user.
For the above points, here are your answers:
1) This is true.
2) a) That is also true.
2) b) When application goes background, you can only save the data of the current activity that was in foreground. Also, when you kill the application it self (by removing it from recent list), all the activities in the app stack and their saved data (not persistent data) got killed as application is the base for all the activities.
1) When application is in foreground the memory will contain instance
of the Application object, instances of all activities (not killed)
and all the object references that are referenced from one of the
root's (haven't been garbage collected)
> There will only ever be a few such processes in the system, and these
> will only be killed as a last resort if memory is so low that not even
> these processes can continue to run. Generally, at this point, the
> device has reached a memory paging state, so this action is required
> in order to keep the user interface responsive.
2) When application goes to background, at some point the Android
Framework can:
.
a) Kill the whole process given to the purpose of the application
which will essentialy erase all the objects from the memory
> These processes have no direct impact on the user experience. Provided
> they implement their Activity life-cycle correctly (see Activity for
> more details), the system can kill such processes at any time to
> reclaim memory for one of the three previous processes types. Usually
> there are many of these processes running, so they are kept in an LRU
> list to ensure the process that was most recently seen by the user is
> the last to be killed when running low on memory.
b) Kill ONLY (so essentialy no other object reference will be deleted)
the activities (by finishing them and in essence any fragments as
well) saving their states and creating the Activities Stack and
leaving anything else (Application object, any other static objects,
references that are reachable from any of the roots).
Partially as in point 2.a.'s explanation
> Usually there are many of these processes running, so they are kept in an LRU
> list to ensure the process that was most recently seen by the user is
> the last to be killed when running low on memory.
Source - developer.android.com
Well this thing depends upon how Android OS operates. Android Device is an embedded System but works almost same as a PC and when I say Android as an OS, it will definetely have all the features of an OS. The thing which you are pointing upon is the Memory Management and Scheduling feature of Android OS.
MMU(Memory Management Unit) logically give preference to currently executing task i.e ur launcher or any other Application which u r working upon. Two things I want to answer which can help u bit more:
Views (whether xml generated or Javacode generated, they are dynamically generated.).
Android OS runs all apps as a process with sub processes(Activities) on a Dalvik Virtual Machine.
All your Activities before they are created they are null, when they are created then their instance is generated. Upon opening them again their saved instance is again viewd(Concept of Singleton Design Pattern).
So let me tell you that I don't think that both of the options are right. What I beleive is following:
1. View will always be generated dynamically.
2. Instance will be saved in Memory.
3. On background going of Application the whole process with instances available will be their in Memory.
Ok, during my search quest in recent weeks I was able to get some more information and now I can answer my own (and hopefully for others) questions:
1) Correct
2a) Correct
2b) False. The android framework, if in need of memory or if due to some other reason it has to "kill/reduce" the application it can do so only by killing the whole process that is dedicated to that application. The android framework can neighter kill chosen activity(ies) or kill all activities but leave all other objects alive (like Application object, singletons etc.)
I have an app which let users to pick an image from sd card and then app process the image. I am downsizing images to 1/5 of avialable vm memory and i do call recycle() for every bitmap in onDestroy() call and i still get out of memory error if i close and open my app multiple times.
There are various memory leak scenarios in Android. One way to track them down is to use the Traceview tool http://developer.android.com/guide/developing/debugging/debugging-tracing.html.
For more info on common Android memory leak problems see http://android-developers.blogspot.co.uk/2009/01/avoiding-memory-leaks.html
Note that when you finish the last Activity of the app the Java process of your app may (in most cases will) be alive meaning all static stuff is still alive when you "start" the app again. Do you store any heavy objects in static fields?
Also note that according to the Activity life-cycle the onDestroy() is not guaranteed to be called. However I don't think this is related, because when you (versus the OS) close the Activity (either by pressing 'Back' button or by calling finish() from the code) then OS always calls onDestroy().
In general, without seeing the code it is difficult to say what happens.
When i am put my application to the background and again awake it means all the Global variables are cleared.This is not happening always but at rare case only.I guess that could be memory crash only.Why global values are cleared? how to recover from this?
This might be the way Android works. Just because you close your last activity in your application doesn't mean that your application is cleared from memory. If Android doesn't need the memory space taken up by your application it won't necessarily be killed right away by Android. Also the garbage collector has it's own life cycle which doesn't necessarily get triggered on each activity destroy.
You can try this: Start Angry Birds and start playing around, fire off some "crazy chickins". Press the home button in the middle of an ongoing game and start Angry Birds directly again. Notice how you end up on the very same level you just "home-ed" out from. Press the home button again and start another application (the browser is usually memory hungry). After some time start Angry Birds again and notice how you'll have to go through the entire start up sequence again (i.e. you don't necessarily end up in the middle of the game, on the level you previously left).
If you really, really need to maintain application state, regardless of GC run or no-run, you should probably use SharedPreferences or a SQLite database. You can read up more on these concepts here: http://developer.android.com/guide/topics/data/data-storage.html
I'm not sure whether I need to add an exit button to my app. Is there any point to doing this? And if on exiting one activity or service is not .finish() or closed properly could this cause a lot of damage?
You don't need to add en exit button. If you don't, your activity will just be kept in memory until the system reclaims it. It will not consume any cpu.
Of course, if you have any worker threads running you should stop them in onStop() or onPause(), depending on what your threads are doing.
Many applications add an exit button, for some reason. I guess the reason is that they don't trust themselves to write proper code or they don't trust the Android OS to clean up properly.
Not going through the correct finish procedures will not cause any damage to others than yourself.
Anyone who says you don't need an exit button is right but putting one in never hurts. Users like to see a way to exit to the application, it's not about bad programming, it's actually about proper programming, give the user an exit button and if they never use it great and if it's there even better.
You don't need an exit button in your app. This is how android works. The user is not given any way to actually exit the application.
When you call 'finish', the application stack is just pushed to the background. It still exists in the memory. Android itself decides when to close the application(i.e. remove its instance from the memory) and generally this is done when your application becomes the oldest application which was not used for the longest time.
No, you don't. Read up on the activity lifecycle at developer.android.com
On older versions of android you had to be careful not to accidentally leave a background service running and holding resources but that's been reworked.
Guys you're righteous, but there are some cases when Exit button may have a sense. Let's say you're keeping some application-wide global data in YourApplication class (child of Application), e.g. some sensitive data or so. When user closes final activity and it's destroyed Application won't be terminated. As read Android developer resource - developer should not rely on Application.onTerminate() method. You can easily check it - even in case when all activities closed Application still alive. Whenever Application instance alive it's relatively easy to get access to those object and collect data.
I have found 2 ways how to kill Application class instance:
null'ate all object references (which is hardly possible for large projects) then call garbage collection
call
android.os.Process.killProcess(android.os.Process.myPid());
So Exit button may have function to finish all activities, call garbage collection then call killProcess() - which will guarantee safe removing of global data stored in Application.
I agree with above post by barmaley.
Long story short, you don't need to exit your application if your concerns are related to the Android system itself. Don't worry, be happy. And that applies especially for lazy users (remember the old Symbian days).
However, if you have something in mind about your application itself, then please go ahead and do it. You can finish the activity, nullify and kill. Just be reasonable because, as always, common sense is going to be better than all the tutorials and references in the world.
Anyway, just my 2c.
From a technical perspective, no, you don't need to add a quit button for all the very good reasons listed here.
Unfortunately users aren't informed in this way and regularly drop review scores because they have to 'use a task killer' or 'force close' your app.
It is a regular request and criticism in reviews/feedback for my app. So it may be necessary to appease users.
I think an exit button can provide the user with assurance that your app is closed.
I know, that it still doesn't mean that the app is definitely closed, but if the user feels more in control with an exit button then I say it is a good idea.
When I first started coding for Android, I thought it was a good idea to manually exit my main activity. What I discovered is that closing the activity via stopSelf leads to corrupt instanceState data, which caused a lot of ANRs when the activity was opened again.
The Activity Lifecycle document is information directly from the Google framework engineers. Every word is for a reason.
Consider that garbage collection takes cpu. This may seem trivial, but in designing a framework for a mobile platform, wouldn't you try to cache as much in memory as possible in case it was needed again, as cpu time = battery, and loading from flash is expensive?
GCing an entire app is non-trivial. Especially when the activity might be used repeatedly. The design had to consider all possible use cases. Cacheing makes sense. The system is designed with this principle.
I would say that not following the Activity Lifecycle document is asking for problems.
Some apps alter the configuration of the device while running or consume lots of CPU or data. You may want to give users an option to Exit the app altogether.
There are proper usecases for an Exit button.
For example, an app i made also needs to manage WiFi networks: the device configuration is changed continuously. Terrific and all while app is in active use, in this case a user would expect the behavior to effectively stop after exiting the application.
So my application has an Exit button mainly to cleanup the WiFi configs it created. I could make a button Stop and Cleanup, but no user would understand. They just want to turn the app off, thus Exit.
App running: wifi managed by app.
App exited: diy/android wifi.
Right now, choosing Exit in my application does the cleanup followed by a finish(), but the application itself lingers in the background. Functionally ok but confusing users. I could make a toggle action named "wifi feature on/off" but that wont make things simpler.