Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a854c13 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Some small tweaks to improve memory management."

parents 4245ab34 162bc0ea
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.text.method.TextKeyListener;
import android.util.AttributeSet;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.view.ActionMode;
import android.view.ContextMenu;
@@ -642,6 +643,7 @@ public class Activity extends ContextThemeWrapper
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2 {
    private static final String TAG = "Activity";
    private static final boolean DEBUG_LIFECYCLE = false;

    /** Standard activity result: operation canceled. */
    public static final int RESULT_CANCELED    = 0;
@@ -865,6 +867,7 @@ public class Activity extends ContextThemeWrapper
     * @see #onPostCreate
     */
    protected void onCreate(Bundle savedInstanceState) {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
        if (mLastNonConfigurationInstances != null) {
            mAllLoaderManagers = mLastNonConfigurationInstances.loaders;
        }
@@ -1013,6 +1016,7 @@ public class Activity extends ContextThemeWrapper
     * @see #onResume
     */
    protected void onStart() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this);
        mCalled = true;
        
        if (!mLoadersStarted) {
@@ -1073,6 +1077,7 @@ public class Activity extends ContextThemeWrapper
     * @see #onPause
     */
    protected void onResume() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);
        getApplication().dispatchActivityResumed(this);
        mCalled = true;
    }
@@ -1131,6 +1136,7 @@ public class Activity extends ContextThemeWrapper
    final void performSaveInstanceState(Bundle outState) {
        onSaveInstanceState(outState);
        saveManagedDialogs(outState);
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
    }

    /**
@@ -1261,6 +1267,7 @@ public class Activity extends ContextThemeWrapper
     * @see #onStop
     */
    protected void onPause() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this);
        getApplication().dispatchActivityPaused(this);
        mCalled = true;
    }
@@ -1347,6 +1354,7 @@ public class Activity extends ContextThemeWrapper
     * @see #onDestroy
     */
    protected void onStop() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this);
        if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
        getApplication().dispatchActivityStopped(this);
        mCalled = true;
@@ -1381,6 +1389,7 @@ public class Activity extends ContextThemeWrapper
     * @see #isFinishing
     */
    protected void onDestroy() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
        mCalled = true;

        // dismiss any dialogs we are managing.
@@ -1432,6 +1441,7 @@ public class Activity extends ContextThemeWrapper
     * @param newConfig The new device configuration.
     */
    public void onConfigurationChanged(Configuration newConfig) {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onConfigurationChanged " + this + ": " + newConfig);
        mCalled = true;

        mFragments.dispatchConfigurationChanged(newConfig);
@@ -1613,11 +1623,13 @@ public class Activity extends ContextThemeWrapper
    }

    public void onLowMemory() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onLowMemory " + this);
        mCalled = true;
        mFragments.dispatchLowMemory();
    }

    public void onTrimMemory(int level) {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onTrimMemory " + this + ": " + level);
        mCalled = true;
        mFragments.dispatchTrimMemory(level);
    }
+23 −7
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ public final class ActivityThread {
    private static final boolean DEBUG_BACKUP = true;
    private static final boolean DEBUG_CONFIGURATION = false;
    private static final boolean DEBUG_SERVICE = false;
    private static final boolean DEBUG_MEMORY_TRIM = false;
    private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
    private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
    private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
@@ -2779,9 +2780,21 @@ public final class ActivityThread {
        performStopActivityInner(r, null, false, saveState);
    }

    private static class StopInfo {
    private static class StopInfo implements Runnable {
        ActivityClientRecord activity;
        Bundle state;
        Bitmap thumbnail;
        CharSequence description;

        @Override public void run() {
            // Tell activity manager we have been stopped.
            try {
                if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
                ActivityManagerNative.getDefault().activityStopped(
                    activity.token, state, thumbnail, description);
            } catch (RemoteException ex) {
            }
        }
    }

    private static final class ProviderRefCount {
@@ -2911,12 +2924,14 @@ public final class ActivityThread {
            QueuedWork.waitToFinish();
        }

        // Tell activity manager we have been stopped.
        try {
            ActivityManagerNative.getDefault().activityStopped(
                r.token, r.state, info.thumbnail, info.description);
        } catch (RemoteException ex) {
        }
        // Schedule the call to tell the activity manager we have
        // stopped.  We don't do this immediately, because we want to
        // have a chance for any other pending work (in particular memory
        // trim requests) to complete before you tell the activity
        // manager to proceed and allow us to go fully into the background.
        info.activity = r;
        info.state = r.state;
        mH.post(info);
    }

    final void performRestartActivity(IBinder token) {
@@ -3749,6 +3764,7 @@ public final class ActivityThread {
    }

    final void handleTrimMemory(int level) {
        if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
        WindowManagerImpl.getDefault().trimMemory(level);
        ArrayList<ComponentCallbacks2> callbacks;

+16 −15
Original line number Diff line number Diff line
@@ -432,9 +432,11 @@ public class WindowManagerImpl implements WindowManager {
     */
    public void trimMemory(int level) {
        if (HardwareRenderer.isAvailable()) {
            // On low and medium end gfx devices
            if (!ActivityManager.isHighEndGfx(getDefaultDisplay())) {
                if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
            // On low-end gfx devices we trim when memory is moderate;
            // on high-end devices we do this when low.
            if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
                    || (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE
                            && !ActivityManager.isHighEndGfx(getDefaultDisplay()))) {
                // Destroy all hardware surfaces and resources associated to
                // known windows
                synchronized (this) {
@@ -449,7 +451,6 @@ public class WindowManagerImpl implements WindowManager {
                mNeedsEglTerminate = true;
                return;
            }
            }
            HardwareRenderer.trimMemory(level);
        }
    }
+3 −1
Original line number Diff line number Diff line
@@ -886,7 +886,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
            // the existing GL resources for the html5 video will be destroyed
            // at native side.
            // Here we just need to clean up the Surface Texture which is static.
            if (level >= TRIM_MEMORY_UI_HIDDEN) {
                HTML5VideoInline.cleanupSurfaceTexture();
            }
            WebViewClassic.nativeOnTrimMemory(level);
        }

+49 −43
Original line number Diff line number Diff line
@@ -13444,7 +13444,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            // an earlier hidden adjustment that isn't really for us... if
            // so, use the new hidden adjustment.
            if (!recursed && app.hidden) {
                app.curAdj = app.curRawAdj = hiddenAdj;
                app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
            }
            return app.curRawAdj;
        }
@@ -13468,7 +13468,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            // below foreground, so it is not worth doing work for it.
            app.adjType = "fixed";
            app.adjSeq = mAdjSeq;
            app.curRawAdj = app.maxAdj;
            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
            app.foregroundActivities = false;
            app.keeping = true;
            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
@@ -13545,6 +13545,8 @@ public final class ActivityManagerService extends ActivityManagerNative
            app.adjType = "bg-empty";
        }
        boolean hasStoppingActivities = false;
        // Examine all activities if not already foreground.
        if (!app.foregroundActivities && activitiesSize > 0) {
            for (int j = 0; j < activitiesSize; j++) {
@@ -13559,15 +13561,20 @@ public final class ActivityManagerService extends ActivityManagerNative
                    app.hidden = false;
                    app.foregroundActivities = true;
                    break;
                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
                        || r.state == ActivityState.STOPPING) {
                    // Only upgrade adjustment.
                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                        app.adjType = "stopping";
                        app.adjType = "pausing";
                    }
                    app.hidden = false;
                    app.foregroundActivities = true;
                } else if (r.state == ActivityState.STOPPING) {
                    // We will apply the actual adjustment later, because
                    // we want to allow this process to immediately go through
                    // any memory trimming that is in effect.
                    app.hidden = false;
                    app.foregroundActivities = true;
                    hasStoppingActivities = true;
                }
            }
        }
@@ -13625,7 +13632,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        // this gives us a baseline and makes sure we don't get into an
        // infinite recursion.
        app.adjSeq = mAdjSeq;
        app.curRawAdj = adj;
        app.curRawAdj = app.nonStoppingAdj = adj;
        if (mBackupTarget != null && app == mBackupTarget.app) {
            // If possible we want to avoid killing apps while they're being backed up
@@ -13882,6 +13889,28 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
        }
        if (adj == ProcessList.SERVICE_ADJ) {
            if (doingAll) {
                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
                mNewNumServiceProcs++;
            }
            if (app.serviceb) {
                adj = ProcessList.SERVICE_B_ADJ;
            }
        } else {
            app.serviceb = false;
        }
        app.nonStoppingAdj = adj;
        if (hasStoppingActivities) {
            // Only upgrade adjustment.
            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                app.adjType = "stopping";
            }
        }
        app.curRawAdj = adj;
        
        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
@@ -13915,18 +13944,6 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
        }
        if (adj == ProcessList.SERVICE_ADJ) {
            if (doingAll) {
                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
                mNewNumServiceProcs++;
            }
            if (app.serviceb) {
                adj = ProcessList.SERVICE_B_ADJ;
            }
        } else {
            app.serviceb = false;
        }
        app.curAdj = adj;
        app.curSchedGroup = schedGroup;
@@ -14138,7 +14155,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
                // If a process has held a wake lock for more
                // than 50% of the time during this period,
                // that sounds pad.  Kill!
                // that sounds bad.  Kill!
                if (doWakeKills && realtimeSince > 0
                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
                    synchronized (stats) {
@@ -14186,23 +14203,6 @@ public final class ActivityManagerService extends ActivityManagerNative
        computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
        if (app.curRawAdj != app.setRawAdj) {
            if (false) {
                // Removing for now.  Forcing GCs is not so useful anymore
                // with Dalvik, and the new memory level hint facility is
                // better for what we need to do these days.
                if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
                        && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
                    // If this app is transitioning from foreground to
                    // non-foreground, have it do a gc.
                    scheduleAppGcLocked(app);
                } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
                        && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
                    // Likewise do a gc when an app is moving in to the
                    // background (such as a service stopping).
                    scheduleAppGcLocked(app);
                }
            }
            if (wasKeeping && !app.keeping) {
                // This app is no longer something we want to keep.  Note
                // its current wake lock time to later know to kill it if
@@ -14319,6 +14319,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        if (factor < 1) factor = 1;
        int step = 0;
        int numHidden = 0;
        int numTrimming = 0;
        
        // First update the OOM adjustment for each of the
        // application processes based on their current state.
@@ -14363,6 +14364,11 @@ public final class ActivityManagerService extends ActivityManagerNative
                    app.killedBackground = true;
                    Process.killProcessQuiet(app.pid);
                }
                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
                        && !app.killedBackground) {
                    numTrimming++;
                }
            }
        }
@@ -14376,7 +14382,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        // memory they want.
        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
            final int N = mLruProcesses.size();
            factor = numHidden/3;
            factor = numTrimming/3;
            int minFactor = 2;
            if (mHomeProcess != null) minFactor++;
            if (mPreviousProcess != null) minFactor++;
@@ -14393,8 +14399,8 @@ public final class ActivityManagerService extends ActivityManagerNative
            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
            for (i=0; i<N; i++) {
                ProcessRecord app = mLruProcesses.get(i);
                if (app.curAdj >= ProcessList.HOME_APP_ADJ
                        && app.curAdj != ProcessList.SERVICE_B_ADJ
                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
                        && !app.killedBackground) {
                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
                        try {
@@ -14426,7 +14432,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                                break;
                        }
                    }
                } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
                            && app.thread != null) {
                        try {
@@ -14437,7 +14443,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                    }
                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
                } else {
                    if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
                            && app.pendingUiClean) {
                        // If this application is now in the background and it
                        // had done UI, then give it the special trim level to
@@ -14464,7 +14470,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            final int N = mLruProcesses.size();
            for (i=0; i<N; i++) {
                ProcessRecord app = mLruProcesses.get(i);
                if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
                        && app.pendingUiClean) {
                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
                            && app.thread != null) {
Loading