29

I have an activity and I call the finish() method and the activity is not cleared from memory.

After calling finish() , I see that the method onDestroy() is executed successfully (and I clear all my variables and stuff in there).

Should it be cleared from memory or its how android works? As I understand the LifeCycle of the Activity is finished.

And if it keeps the app in memory so it runs faster the 2nd time the user uses it, what kind of objects can I leave in memory to reuse? If I understand correctly, I am suppose to clear everything on onDestroy.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Daniel Benedykt
  • 6,496
  • 12
  • 51
  • 73
  • "I have an activity and I call the finish() method and the activity is not cleared from memory." -- how, *precisely*, have you determined this? – CommonsWare Dec 29 '09 at 22:26
  • 2
    If you use DDMS from eclipse, you can debug to make sure it runs thru onDestroy() and after that you can still see the process in the device and you can even see the heap size that is taken, and you can dump the memory to analyze. IF I am not mistaken for me this means that is still in memory, correct ? – Daniel Benedykt Dec 30 '09 at 11:28

7 Answers7

36

Android keeps processes around in case the user wants to restart the app, this makes the startup phase faster. The process will not be doing anything and if memory needs to be reclaimed, the process will be killed. Don't worry about it :)

Romain Guy
  • 97,993
  • 18
  • 219
  • 200
  • 1
    Does this also apply for "subactivities", means if it's not the last activity open in my app? Say: if I open activity B from activity A, then B.finish(), would Android eventually keep B in memory and would I eventually also still see B in my hprof dump (in case Android didn't need to reclaim memory for elsewhere)? – Mathias Conradt Jun 26 '10 at 08:10
  • Yes, Activity B will still be memory. Activity B will only be removed if Android needs memory for something else. – ChuongPham Dec 28 '13 at 17:32
  • "Dont worry about sending app to background instead of removing it from memory completely?" Are you a serious programmer? How about Bank or other security fragile applications? – TomeeNS Nov 23 '15 at 02:44
  • If you are worried about the memory usage of the retained instances, override onDestory() of the activity/fragment and clear the variables that are holding on to the memory – Joe Maher May 18 '16 at 00:51
31

Best way is firstly use finish() and after that use System.exit(0) to clear static variables. It will give you some free space.

A lot of applications leave working processes and variables what makes me angry. After 30 minutes of using memory is full and i have to run Task Manager - Lvl 2 clear memory

Its not true that is cousing problems i've tried it for over 3 years in my apps. Never get crashed or restart after using Exit()

Raghav Sood
  • 81,899
  • 22
  • 187
  • 195
Tefel
  • 411
  • 4
  • 3
  • 2
    This is working for me, too. I had a situation in which I was pressing the back button to exit the app, per normal behavior, and it was leaving memory around. The next time I started, the memory just accumulated, and if I did this about five times, I ran out of heap (24MB on test device). finish() alone was not doing the job. I suspect that the Splash activity I use to let the user know that we'll be right there may somehow have prevented memory from getting reclaimed on exit. It does seem less than adept to use such a crude tool, but when you're closing the app, what is the difference? – Carl Nov 06 '12 at 14:25
  • 2
    My game app uses 225MB on initial run. After using finish() and restarting, it uses 400MB this second time, running significantly slower (my Samsung Galaxy Tab S2 has a 524M heap). On other less heaped devices it just crashes with an 'out of memory' error on the second run. Using 'System.exit(0)' after 'finish()' appears to fix this. I notice 'finish()' does not immediately stop the code run, as 'System.exit(0)' still is reached when placed after 'finish()'. However, 'System.exit(0)' does appear to halt the code run at its line. – Androidcoder Dec 21 '15 at 18:11
  • Caveat: I tested with my app System.exit(0) would be problematic for recreating the view after rotating the device if done on a fragment – ND27 Mar 31 '16 at 05:48
  • 2
    Under Samsung Android 5.1.1 my app reliably crashed with OOM when the user triggered `onBackPressed()`, which calls `finish()`, which calls `onDestroy()`, which calls `super.onDestroy()` as its first step. `super.onDestroy()` was not stopping the app; it kept running and if the user restarted it from Task Manager it went through `onCreate()` w/o having freed resources, attempting to allocate a bitmap structure which it was already using. **`System.exit(0)` is the only solution I've found for this**. It's not the documented approach, but maybe it's working around a problem with the OS. – CODE-REaD Nov 09 '16 at 01:04
  • **UPDATE:** Android's default GC was being defeated by my looping methods which weren't being stopped by Android's `onDestroy()`. This held true even if my app did *not* super `onBackPressed()` or `onDestroy()`. By setting a flag which caused my methods to terminate at `onDestroy()` I apparently allow GC to operate and remove the cause of OOM crashes *without needing to call `System.exit(0)`.* ***A significant difference in this approach is that the app's process now continues to run*** after `onDestroy()`, whereas calling `System.exit(0)` from `onDestroy()` killed the process. – CODE-REaD Nov 09 '16 at 16:20
12

Try using

System.exit(0);

Zahid
  • 121
  • 1
  • 2
6

Once onDestroy() gets called, your activity is doomed. Period.

That being said, the process (and hence address space) allocated to your application might still be in use by another part of your application -- another activity or service. It's also possible that your process is empty and the OS just hasn't gotten around to reclaiming it yet; it's not instant.

See the Process Lifecycle document for more information:
http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle

Regardless, if your activity is relaunched, it will have to go through the entire startup sequence again, starting with onCreate(). Do not assume that anything can implicitly be reused.

Trevor Johns
  • 15,682
  • 3
  • 55
  • 54
  • I believe this is not totally true. I don't believe the Activity is doom, because there are ways to leak memory and then the Activity will live forever. – Daniel Benedykt Dec 30 '09 at 16:27
  • Even if an activity leaks memory, when the OS kills the process the memory will be reclaimed. Just like when you terminate a process on a desktop OS. – Trevor Johns Dec 30 '09 at 22:27
4

If you need to close application from subactivity, I may suggest you to made it in such a way: 1) from activity A call activity B as startActivityForResult(intent, REQUEST_CODE);

Intent intent = new Intent()
            .setClass(ActivityA.this, ActivityB.class);
            startActivityForResult(intent, REQUEST_CODE);

2) in activity A you should add method:

protected void onActivityResult(int requestCode, int resultCode,
        Intent data) {
    if (requestCode == REQUEST_CODE) {
        if (resultCode == RESULT_CLOSE_APPLICATION) {
            this.finish();
        }
    }
}

3) in activity B call finish:

this.setResult(RESULT_CLOSE_APPLICATION);
this.finish();
Anton Derevyanko
  • 3,405
  • 1
  • 24
  • 32
1

According to this presentation from Google I/O 2008, Finish should also cause the process to be killed, but I wrote a quick application to test this and on Android 1.5 it does not.

As Romain said (who incidentally is a UI Toolkit engineer for Android), your process will just sit there doing nothing anyways, so it is nothing to worry about.

sud007
  • 5,824
  • 4
  • 56
  • 63
Frank
  • 1,426
  • 1
  • 14
  • 14
1

As a quick fix you can use the folowing to kill your app:

android.os.Process.killProcess(android.os.Process.myPid());

But I would not recommend this for commercial apps because it goes against how the Android memory management system works.

Rab Ross
  • 2,098
  • 22
  • 28