128

Hi I'm wondering how Android is managing memory and I can't find precise answer anywhere. Let's assume I have an application with 5 activities on current activity stack (4 are stopped and 1 is resumed), there is no service connected. I press HOME button so that all of my activities are stopped. I start some other memory consuming application and overall device memory is starting to be low. And the question is

... What will happen to my application?

  1. Can system destroy only one or some of my activities to recover memory?
  2. Will system kill the whole process of my application? Will all activities be nicely destroyed?
  3. What will happen when I get back to my application when it was totally killed? Will it start from beggining (like the first start) or will it try to recover activities to previeous state / if yes - is it only the one on the top of the stack or all of them?

UPDATE:

Before asking this question I've seen Activity lifecycle a few times but it doesn't have answers to my questions. I made some tests and I have some answers. "Stop process" in DDMS was a clue for testing.

I haven't tested answer for question 1, but as guide says:

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.

It seems that one or more of the activities can be destroyed gently(with onDestroy method) without killing the process. You will simply get (onCreate + bundle) when getting back to them.

Question 2 answer:

YES. Generally system kills the whole process this means all data including activities and static fields are destroyed. This is NOT done nicely - you won't get onDestroy or finialize() for any of your paused/stopped activities. This is why saveInstanceState() is called just before onPause method. onPause is basically the last method where you should save something because after this method you could never see onStop or onDestroy. System can just kill the process destroying all of your objects whatever they hold and whatever they are doing.

Question 3 answer:

What will happen when you get back to a killed application?

  • Prior to Android 2.2 - application will start from the beggining, with launcher activity.
  • Starting from 2.2 - system will restore the previous application state. What does it mean? It means that last visible activity will be recreated (onCreate + bundle). What will happen with activity stack? Stack is fine but all activities on it are dead. Each of them will be recreated (onCreate + bundle) when you get back to it with back button. There is one more thing about that:

Normally, the system clears a task (removes all activities from the stack above the root activity) in certain situations when the user re-selects that task from the home screen. Typically, this is done if the user hasn't visited the task for a certain amount of time, such as 30 minutes.

Conclusion?

  1. Don't think that handling activity rotation problems can be solved by android:configChanges="orientation". When you do that you will get many other problems that you are not even aware of.
  2. Test your application with DDMS - Stop process button. See This
  3. Be careful when using static variables. Don't think that when you initialized them in activity 1 - you will have them initialized in activity 2. The only safe place to initialize global statics would be Application class.
  4. Remember that you may never see onStop or onDestroy. Close files/databases, stop downloaders in onPause. When you want app to do something in BG - use foreground Service.

That would be it ... Hope I helped with my essey :)

Community
  • 1
  • 1
Mark
  • 5,466
  • 3
  • 23
  • 24
  • For your assumption, are those 5 activities come from a same app or several different apps? – dumbfingers Jan 17 '13 at 09:53
  • 1
    "I have an application with 5 activities on current activity stack" Of course they are all from my, one, same process application. – Mark Jan 17 '13 at 10:07
  • 4
    Thank you this was exactly my question too... Your question and the answers helped me quite a bit. – craigrs84 Jan 31 '13 at 03:23
  • See also: http://stackoverflow.com/q/11365301/1402846, http://stackoverflow.com/q/5423571/1402846 – Pang Jul 30 '13 at 08:55
  • @Mark: Is this problem solved now? How if it is? – Ameer Moaaviah Oct 24 '13 at 11:32
  • This wasn't a problem but a question. The answer is provided below my question in my UPDATE. It is based on my tests and deep investigation :) – Mark Nov 13 '13 at 10:46
  • Yes, it seems that system can finish process completely or just finish one activity – Stas Jan 13 '15 at 10:46
  • @Mark : Can you tell, what you mean by root activity? top in stack or launcher? – AndiGeeky Aug 05 '17 at 13:33
  • @AndiGeeky yes, this is the Activity started by launcher icon. The text with 'root activity' was taken from android docs – Mark Oct 16 '17 at 20:32
  • I'm having an issue when recovering static variables in this exact situation. When you say "The only safe place to initialize global statics would be Application class" what do you mean by "the Application class"? – Fnr Dec 08 '17 at 17:36
  • This should be accepted question ;0 – Vadim Dec 04 '18 at 09:34
  • U won't find it in android lifecycle. Because services and applications are killed by system APPS not codes. There are some system apps for example Phone Master nowadays ( not really ). And system includes Settings app, System UI etc. I guess it's another app killing the processes in bg not the system itself (check developer options in settings) – DiLDoST Aug 15 '22 at 22:50

2 Answers2

33

First please have a look at this:

img1

onPause() Called when the system is about to start resuming a previous activity. This is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, etc. Implementations of this method must be very quick because the next activity will not be resumed until this method returns. Followed by either onResume() if the activity returns back to the front, or onStop() if it becomes invisible to the user.

onStop() Called when the activity is no longer visible to the user, because another activity has been resumed and is covering this one. This may happen either because a new activity is being started, an existing one is being brought in front of this one, or this one is being destroyed. Followed by either onRestart() if this activity is coming back to interact with the user, or onDestroy() if this activity is going away.

So, when you press "HOME" button on your device, your current foreground activity is put onto onPause() then onStop(), the other 4 should remain onStop()

According to Google's Documents:

  • If an activity in the foreground of the screen (at the top of the stack), it is active or running.
  • If an activity has lost focus but is still visible (that is, a new non-full-sized or transparent activity has focus on top of your activity), it is paused. A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed by the system in extreme low memory situations.
  • If an activity is completely obscured by another activity, it is stopped. It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere.
  • 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. When it is displayed again to the user, it must be completely restarted and restored to its previous state.

And, for the process lifecycle:

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.

All the quotes above are come from: Android Developers Reference: Activity

It is confirmed that the system can destroy non-acitve activities and recycle memories when you launched some memory consuming applications. And you can implement like: isFinishing() in your activity and then using "kill" button in DDMS to detect which of your activities is being dropped by system. But I guess the system will destroy the oldest one first. However it is no point to keep other activities when the "Launch Activity" has been recycled.

UPDATE

Here's some opinions I found from here:

Stopped state

When an activity is not visible, but still in memory, we say it’s in a stopped state. Stopped activity could be brought back to the front to become a Running activity again. Or, it could be destroyed and removed from memory.

The system keeps activities around in a stopped state because it is likely that the user will still want to get back to those activities some time soon, and restarting a stopped activity is far cheaper than starting an activity from scratch. That is because we already have all the objects loaded in memory and simply have to bring it all up to the foreground.

Stopped activities can be removed from memory at any point.

dumbfingers
  • 7,001
  • 5
  • 54
  • 80
  • 4
    The documentation is quite confusing on this issue, however only a whole process can be killed, not individual components (activities, services, etc.). See: http://stackoverflow.com/questions/7536988/android-app-out-of-memory-issues-tried-everything-and-still-at-a-loss/7576275#7576275 – greg7gkb Jul 10 '14 at 21:03
  • This question should be updated with the info in the link of @greg7gkb comment, its misleading – Luke De Feo Jul 12 '16 at 15:46
1

Can system destroy only one or some of my activities to recover memory?

Yes. Android kills activities which are running in the background when there is a need for memory. Killing one or all might depend on some conditions. For an instance paused or stopped can make android kill an activity or a process itself. Here under Activity Lifecycle you can get the below points. I recommend you to go through that page completely. It will definitely clear your doubts.

If an activity has lost focus but is still visible (that is, a new non-full-sized or transparent activity has focus on top of your activity), it is paused. A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed by the system in extreme low memory situations.

If an activity is completely obscured by another activity, it is stopped. It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere.

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. When it is displayed again to the user, it must be completely restarted and restored to its previous state.


Will system kill the whole process of my application? Will all activities be nicely destroyed?

Activity pertains to an individual whereas process pertains to group of activities. Look at the third point above again it kills the process as mentioned.


What will happen when I get back to my application when it was totally killed?

Its similar to restart . Again the third point will give you some answers like When it is displayed again to the user, it must be completely restarted and restored to its previous state

Get some more information about memory related stuffs here.

Edit:
All activities in an application runs in a single process. So when a process is killed all the activities no matter 5 or 10 will be killed i.e., restarted. Restart will cause your application to start from a beginning no saved states.

Community
  • 1
  • 1
Vinay
  • 6,891
  • 4
  • 32
  • 50
  • 2
    Ive seen Activity Lifecycle at least 5 times but it doesn't answer my questions. What you said would mean when my app process is killed - when I get back to app it is restored to it's previous state. So when I had 5 stopped activities .. did they all die (onDestroy invoked) when process was killed? When I got back to my app were all activities restored (onCreate + bundle) or only the one on the top of the stack (visible to user)? – Mark Jan 17 '13 at 15:22
  • 1
    All activities in an application runs in a single process. So when a process is killed all the activities no matter 5 or 10 will be killed i.e., restarted. Restart will cause your application to start from a beginning no saved states.. – Vinay Jan 18 '13 at 05:26
  • 1
    Almost true, but not for 2.2 and above. See my UPDATE at the top of the page. – Mark Jan 18 '13 at 08:52
  • 1
    No, this is not true and has not ever been true. It's confusing based on the docs, but see: http://stackoverflow.com/questions/7536988/android-app-out-of-memory-issues-tried-everything-and-still-at-a-loss/7576275#7576275 – greg7gkb Jul 10 '14 at 21:01
  • *By default* all activities and services in an app run in the same process, however the manifest can configure any of them to run in a different process. – Chris Stratton Apr 16 '15 at 17:36
  • 2
    @JJPA Android cannot destroy single Activities to reclaim memory, it only destroys processes. See this answer by Dianne Hackbor, Android core team member involved in the "out of memory killer" implementation: http://stackoverflow.com/a/7576275/1290264. – bcorso Jul 10 '15 at 19:28
  • "Restart will cause your application to start from a beginning no saved states." Is this still true? When come back to a killed process(app), the activity and fragment will re-create and restore to the state it was left instead of starting from beginning. – BabyishTank Oct 28 '21 at 22:42