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

Commit 65b345fa authored by Romain Guy's avatar Romain Guy
Browse files

Reclaim more memory, more often.

Yay.

Change-Id: I04557ad575c307a55088549f48f0e9ad994b7275
parent 6d7475d6
Loading
Loading
Loading
Loading
+64 −56
Original line number Diff line number Diff line
@@ -123,7 +123,6 @@ public final class ActivityThread {
    /** @hide */
    public static final String TAG = "ActivityThread";
    private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
    private static final boolean DEBUG = false;
    static final boolean localLOGV = false;
    static final boolean DEBUG_MESSAGES = false;
    /** @hide */
@@ -163,7 +162,7 @@ public final class ActivityThread {
            = new ArrayList<Application>();
    // set of instantiated backup agents, keyed by package name
    final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>();
    static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal();
    static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>();
    Instrumentation mInstrumentation;
    String mInstrumentationAppDir = null;
    String mInstrumentationAppPackage = null;
@@ -410,9 +409,9 @@ public final class ActivityThread {
        CompatibilityInfo info;
    }
    
    native private void dumpGraphicsInfo(FileDescriptor fd);
    private native void dumpGraphicsInfo(FileDescriptor fd);

    private final class ApplicationThread extends ApplicationThreadNative {
    private class ApplicationThread extends ApplicationThreadNative {
        private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
        private static final String ONE_COUNT_COLUMN = "%21s %8d";
        private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
@@ -734,13 +733,13 @@ public final class ActivityThread {
            FileOutputStream fout = new FileOutputStream(fd);
            PrintWriter pw = new PrintWriter(fout);
            try {
                return dumpMemInfo(fd, pw, args);
                return dumpMemInfo(pw, args);
            } finally {
                pw.flush();
            }
        }

        private Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
        private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, String[] args) {
            long nativeMax = Debug.getNativeHeapSize() / 1024;
            long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
            long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
@@ -754,7 +753,7 @@ public final class ActivityThread {
            long dalvikFree = runtime.freeMemory() / 1024;
            long dalvikAllocated = dalvikMax - dalvikFree;
            long viewInstanceCount = ViewDebug.getViewInstanceCount();
            long viewRootInstanceCount = ViewDebug.getViewAncestorInstanceCount();
            long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
            long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
            long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
            int globalAssetCount = AssetManager.getGlobalAssetCount();
@@ -868,7 +867,7 @@ public final class ActivityThread {
            int otherPrivateDirty = memInfo.otherPrivateDirty;

            for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
                printRow(pw, HEAP_COLUMN, memInfo.getOtherLabel(i),
                printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
                        memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i),
                        memInfo.getOtherPrivateDirty(i), "", "", "");
                otherPss -= memInfo.getOtherPss(i);
@@ -885,7 +884,7 @@ public final class ActivityThread {

            pw.println(" ");
            pw.println(" Objects");
            printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewAncestors:",
            printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
                    viewRootInstanceCount);

            printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
@@ -937,6 +936,7 @@ public final class ActivityThread {
        @Override
        public void dumpGfxInfo(FileDescriptor fd, String[] args) {
            dumpGraphicsInfo(fd);
            WindowManagerImpl.getDefault().dumpGfxInfo(fd);
        }

        private void printRow(PrintWriter pw, String format, Object...objs) {
@@ -959,7 +959,7 @@ public final class ActivityThread {
        }
    }

    private final class H extends Handler {
    private class H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;
        public static final int PAUSE_ACTIVITY          = 101;
        public static final int PAUSE_ACTIVITY_FINISHING= 102;
@@ -1220,7 +1220,7 @@ public final class ActivityThread {
        }
    }

    private final class Idler implements MessageQueue.IdleHandler {
    private class Idler implements MessageQueue.IdleHandler {
        public final boolean queueIdle() {
            ActivityClientRecord a = mNewActivities;
            if (a != null) {
@@ -1231,12 +1231,13 @@ public final class ActivityThread {
                    if (localLOGV) Slog.v(
                        TAG, "Reporting idle of " + a +
                        " finished=" +
                        (a.activity != null ? a.activity.mFinished : false));
                        (a.activity != null && a.activity.mFinished));
                    if (a.activity != null && !a.activity.mFinished) {
                        try {
                            am.activityIdle(a.token, a.createdConfig);
                            a.createdConfig = null;
                        } catch (RemoteException ex) {
                            // Ignore
                        }
                    }
                    prev = a;
@@ -1256,7 +1257,7 @@ public final class ActivityThread {
        }
    }

    private final static class ResourcesKey {
    private static class ResourcesKey {
        final private String mResDir;
        final private float mScale;
        final private int mHash;
@@ -1282,17 +1283,17 @@ public final class ActivityThread {
        }
    }

    public static final ActivityThread currentActivityThread() {
    public static ActivityThread currentActivityThread() {
        return sThreadLocal.get();
    }

    public static final String currentPackageName() {
    public static String currentPackageName() {
        ActivityThread am = currentActivityThread();
        return (am != null && am.mBoundApplication != null)
            ? am.mBoundApplication.processName : null;
    }

    public static final Application currentApplication() {
    public static Application currentApplication() {
        ActivityThread am = currentActivityThread();
        return am != null ? am.mInitialApplication : null;
    }
@@ -1337,7 +1338,7 @@ public final class ActivityThread {
        return config;
    }

    private final Configuration mMainThreadConfig = new Configuration();
    private Configuration mMainThreadConfig = new Configuration();
    Configuration applyConfigCompatMainThread(Configuration config, CompatibilityInfo compat) {
        if (config == null) {
            return null;
@@ -1456,6 +1457,7 @@ public final class ActivityThread {
            ai = getPackageManager().getApplicationInfo(packageName,
                    PackageManager.GET_SHARED_LIBRARY_FILES);
        } catch (RemoteException e) {
            // Ignore
        }

        if (ai != null) {
@@ -1505,7 +1507,7 @@ public final class ActivityThread {
        }
    }

    private final LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
    private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
            ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
        synchronized (mPackages) {
            WeakReference<LoadedApk> ref;
@@ -1712,15 +1714,15 @@ public final class ActivityThread {

    // if the thread hasn't started yet, we don't have the handler, so just
    // save the messages until we're ready.
    private final void queueOrSendMessage(int what, Object obj) {
    private void queueOrSendMessage(int what, Object obj) {
        queueOrSendMessage(what, obj, 0, 0);
    }

    private final void queueOrSendMessage(int what, Object obj, int arg1) {
    private void queueOrSendMessage(int what, Object obj, int arg1) {
        queueOrSendMessage(what, obj, arg1, 0);
    }

    private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
    private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
        synchronized (this) {
            if (DEBUG_MESSAGES) Slog.v(
                TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
@@ -1743,7 +1745,7 @@ public final class ActivityThread {
        queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci);
    }

    private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
@@ -1861,7 +1863,7 @@ public final class ActivityThread {
        return activity;
    }

    private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
@@ -1917,11 +1919,12 @@ public final class ActivityThread {
                ActivityManagerNative.getDefault()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null);
            } catch (RemoteException ex) {
                // Ignore
            }
        }
    }

    private final void deliverNewIntents(ActivityClientRecord r,
    private void deliverNewIntents(ActivityClientRecord r,
            List<Intent> intents) {
        final int N = intents.size();
        for (int i=0; i<N; i++) {
@@ -1949,7 +1952,7 @@ public final class ActivityThread {
        }
    }

    private final void handleNewIntent(NewIntentData data) {
    private void handleNewIntent(NewIntentData data) {
        performNewIntents(data.token, data.intents);
    }

@@ -1964,7 +1967,7 @@ public final class ActivityThread {
        return sCurrentBroadcastIntent.get();
    }

    private final void handleReceiver(ReceiverData data) {
    private void handleReceiver(ReceiverData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
@@ -1976,7 +1979,7 @@ public final class ActivityThread {

        IActivityManager mgr = ActivityManagerNative.getDefault();

        BroadcastReceiver receiver = null;
        BroadcastReceiver receiver;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            data.intent.setExtrasClassLoader(cl);
@@ -2026,7 +2029,7 @@ public final class ActivityThread {
    }

    // Instantiate a BackupAgent and tell it that it's alive
    private final void handleCreateBackupAgent(CreateBackupAgentData data) {
    private void handleCreateBackupAgent(CreateBackupAgentData data) {
        if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);

        // no longer idle; we have backup work to do
@@ -2091,7 +2094,7 @@ public final class ActivityThread {
    }

    // Tear down a BackupAgent
    private final void handleDestroyBackupAgent(CreateBackupAgentData data) {
    private void handleDestroyBackupAgent(CreateBackupAgentData data) {
        if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);

        LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
@@ -2110,7 +2113,7 @@ public final class ActivityThread {
        }
    }

    private final void handleCreateService(CreateServiceData data) {
    private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
@@ -2156,7 +2159,7 @@ public final class ActivityThread {
        }
    }

    private final void handleBindService(BindServiceData data) {
    private void handleBindService(BindServiceData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
@@ -2184,7 +2187,7 @@ public final class ActivityThread {
        }
    }

    private final void handleUnbindService(BindServiceData data) {
    private void handleUnbindService(BindServiceData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
@@ -2236,7 +2239,7 @@ public final class ActivityThread {
        }
    }

    private final void handleServiceArgs(ServiceArgsData data) {
    private void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
@@ -2270,7 +2273,7 @@ public final class ActivityThread {
        }
    }

    private final void handleStopService(IBinder token) {
    private void handleStopService(IBinder token) {
        Service s = mServices.remove(token);
        if (s != null) {
            try {
@@ -2465,7 +2468,7 @@ public final class ActivityThread {
    private Bitmap mAvailThumbnailBitmap = null;
    private Canvas mThumbnailCanvas = null;

    private final Bitmap createThumbnailBitmap(ActivityClientRecord r) {
    private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
        Bitmap thumbnail = mAvailThumbnailBitmap;
        try {
            if (thumbnail == null) {
@@ -2515,7 +2518,7 @@ public final class ActivityThread {
        return thumbnail;
    }

    private final void handlePauseActivity(IBinder token, boolean finished,
    private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
@@ -2621,7 +2624,7 @@ public final class ActivityThread {
        CharSequence description;
    }

    private final class ProviderRefCount {
    private class ProviderRefCount {
        public int count;
        ProviderRefCount(int pCount) {
            count = pCount;
@@ -2636,7 +2639,7 @@ public final class ActivityThread {
     * For the client, we want to call onStop()/onStart() to indicate when
     * the activity's UI visibillity changes.
     */
    private final void performStopActivityInner(ActivityClientRecord r,
    private void performStopActivityInner(ActivityClientRecord r,
            StopInfo info, boolean keepShown, boolean saveState) {
        if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
        Bundle state = null;
@@ -2699,7 +2702,7 @@ public final class ActivityThread {
        }
    }

    private final void updateVisibility(ActivityClientRecord r, boolean show) {
    private void updateVisibility(ActivityClientRecord r, boolean show) {
        View v = r.activity.mDecor;
        if (v != null) {
            if (show) {
@@ -2726,7 +2729,7 @@ public final class ActivityThread {
        }
    }

    private final void handleStopActivity(IBinder token, boolean show, int configChanges) {
    private void handleStopActivity(IBinder token, boolean show, int configChanges) {
        ActivityClientRecord r = mActivities.get(token);
        r.activity.mConfigChangeFlags |= configChanges;

@@ -2760,7 +2763,7 @@ public final class ActivityThread {
        }
    }

    private final void handleWindowVisibility(IBinder token, boolean show) {
    private void handleWindowVisibility(IBinder token, boolean show) {
        ActivityClientRecord r = mActivities.get(token);
        
        if (r == null) {
@@ -2785,7 +2788,7 @@ public final class ActivityThread {
        }
    }

    private final void handleSleeping(IBinder token, boolean sleeping) {
    private void handleSleeping(IBinder token, boolean sleeping) {
        ActivityClientRecord r = mActivities.get(token);

        if (r == null) {
@@ -2846,7 +2849,7 @@ public final class ActivityThread {
        WindowManagerImpl.getDefault().reportNewConfiguration(mConfiguration);
    }

    private final void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
    private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
        final int N = results.size();
        for (int i=0; i<N; i++) {
            ResultInfo ri = results.get(i);
@@ -2869,7 +2872,7 @@ public final class ActivityThread {
        }
    }

    private final void handleSendResult(ResultData res) {
    private void handleSendResult(ResultData res) {
        ActivityClientRecord r = mActivities.get(res.token);
        if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
        if (r != null) {
@@ -2915,7 +2918,7 @@ public final class ActivityThread {
        return performDestroyActivity(token, finishing, 0, false);
    }

    private final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
    private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
            int configChanges, boolean getNonConfigInstance) {
        ActivityClientRecord r = mActivities.get(token);
        Class activityClass = null;
@@ -3008,7 +3011,7 @@ public final class ActivityThread {
        return component == null ? "[Unknown]" : component.toShortString();
    }

    private final void handleDestroyActivity(IBinder token, boolean finishing,
    private void handleDestroyActivity(IBinder token, boolean finishing,
            int configChanges, boolean getNonConfigInstance) {
        ActivityClientRecord r = performDestroyActivity(token, finishing,
                configChanges, getNonConfigInstance);
@@ -3123,7 +3126,7 @@ public final class ActivityThread {
        }
    }

    private final void handleRelaunchActivity(ActivityClientRecord tmp) {
    private void handleRelaunchActivity(ActivityClientRecord tmp) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
@@ -3233,7 +3236,7 @@ public final class ActivityThread {
        handleLaunchActivity(r, currentIntent);
    }

    private final void handleRequestThumbnail(IBinder token) {
    private void handleRequestThumbnail(IBinder token) {
        ActivityClientRecord r = mActivities.get(token);
        Bitmap thumbnail = createThumbnailBitmap(r);
        CharSequence description = null;
@@ -3308,7 +3311,7 @@ public final class ActivityThread {
        return callbacks;
    }

    private final void performConfigurationChanged(
    private void performConfigurationChanged(
            ComponentCallbacks cb, Configuration config) {
        // Only for Activity objects, check that they actually call up to their
        // superclass implementation.  ComponentCallbacks is an interface, so
@@ -3452,6 +3455,9 @@ public final class ActivityThread {
            callbacks = collectComponentCallbacksLocked(false, config);
        }
        
        // Cleanup hardware accelerated stuff
        WindowManagerImpl.getDefault().trimLocalMemory();

        if (callbacks != null) {
            final int N = callbacks.size();
            for (int i=0; i<N; i++) {
@@ -3579,7 +3585,7 @@ public final class ActivityThread {
        WindowManagerImpl.getDefault().trimMemory(level);
    }

    private final void handleBindApplication(AppBindData data) {
    private void handleBindApplication(AppBindData data) {
        mBoundApplication = data;
        mConfiguration = new Configuration(data.config);
        mCompatConfiguration = new Configuration(data.config);
@@ -3791,7 +3797,7 @@ public final class ActivityThread {
        }
    }

    private final void installContentProviders(
    private void installContentProviders(
            Context context, List<ProviderInfo> providers) {
        final ArrayList<IActivityManager.ContentProviderHolder> results =
            new ArrayList<IActivityManager.ContentProviderHolder>();
@@ -3825,7 +3831,7 @@ public final class ActivityThread {
        }
    }

    private final IContentProvider getExistingProvider(Context context, String name) {
    private IContentProvider getExistingProvider(Context context, String name) {
        synchronized(mProviderMap) {
            final ProviderClientRecord pr = mProviderMap.get(name);
            if (pr != null) {
@@ -3835,7 +3841,7 @@ public final class ActivityThread {
        }
    }

    private final IContentProvider getProvider(Context context, String name) {
    private IContentProvider getProvider(Context context, String name) {
        IContentProvider existing = getExistingProvider(context, name);
        if (existing != null) {
            return existing;
@@ -4007,7 +4013,7 @@ public final class ActivityThread {
        }
    }

    private final IContentProvider installProvider(Context context,
    private IContentProvider installProvider(Context context,
            IContentProvider provider, ProviderInfo info, boolean noisy) {
        ContentProvider localProvider = null;
        if (provider == null) {
@@ -4027,6 +4033,7 @@ public final class ActivityThread {
                    c = context.createPackageContext(ai.packageName,
                            Context.CONTEXT_INCLUDE_CODE);
                } catch (PackageManager.NameNotFoundException e) {
                    // Ignore
                }
            }
            if (c == null) {
@@ -4086,7 +4093,7 @@ public final class ActivityThread {
        return provider;
    }

    private final void attach(boolean system) {
    private void attach(boolean system) {
        sThreadLocal.set(this);
        mSystemThread = system;
        if (!system) {
@@ -4101,6 +4108,7 @@ public final class ActivityThread {
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
        } else {
            // Don't set application object here -- if the system crashes,
@@ -4166,7 +4174,7 @@ public final class ActivityThread {
        }
    }

    public static final void main(String[] args) {
    public static void main(String[] args) {
        SamplingProfilerIntegration.start();

        // CloseGuard defaults to true and can be quite spammy.  We
+7 −0
Original line number Diff line number Diff line
@@ -54,4 +54,11 @@ public abstract class DisplayList {
     * @return boolean true if the display list is able to be replayed, false otherwise.
     */
    abstract boolean isValid();

    /**
     * Return the amount of memory used by this display list.
     * 
     * @return The size of this display list in bytes
     */
    abstract int getSize();
}
+6 −0
Original line number Diff line number Diff line
@@ -330,6 +330,12 @@ class GLES20Canvas extends HardwareCanvas {

    private static native void nDestroyDisplayList(int displayList);

    static int getDisplayListSize(int displayList) {
        return nGetDisplayListSize(displayList);
    }

    private static native int nGetDisplayListSize(int displayList);

    @Override
    public boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty) {
        return nDrawDisplayList(mRenderer,
+6 −0
Original line number Diff line number Diff line
@@ -82,6 +82,12 @@ class GLES20DisplayList extends DisplayList {
        }
    }

    @Override
    int getSize() {
        if (mFinalizer == null) return 0;
        return GLES20Canvas.getDisplayListSize(mFinalizer.mNativeDisplayList);
    }

    private static class DisplayListFinalizer {
        final int mNativeDisplayList;

+3 −1
Original line number Diff line number Diff line
@@ -934,7 +934,9 @@ public abstract class HardwareRenderer {
        }

        private void destroyHardwareLayer(View view) {
            view.destroyLayer();
            if (view.destroyLayer()) {
                view.invalidate(true);
            }
            if (view instanceof ViewGroup) {
                ViewGroup group = (ViewGroup) view;

Loading