All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.com.android.systemui.util.leak.LeakDetector Maven / Gradle / Ivy

Go to download

A library jar that provides APIs for Applications written for the Google Android Platform.

There is a newer version: 15-robolectric-12650502
Show newest version
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.util.leak;

import android.os.Build;
import android.util.IndentingPrintWriter;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dumpable;
import com.android.systemui.dump.DumpManager;

import java.io.PrintWriter;
import java.util.Collection;

/**
 * Detects leaks.
 */
public class LeakDetector implements Dumpable {

    public static final boolean ENABLED = Build.IS_DEBUGGABLE;

    private final TrackedCollections mTrackedCollections;
    private final TrackedGarbage mTrackedGarbage;
    private final TrackedObjects mTrackedObjects;

    @VisibleForTesting
    public LeakDetector(
            TrackedCollections trackedCollections,
            TrackedGarbage trackedGarbage,
            TrackedObjects trackedObjects,
            DumpManager dumpManager) {
        mTrackedCollections = trackedCollections;
        mTrackedGarbage = trackedGarbage;
        mTrackedObjects = trackedObjects;

        dumpManager.registerDumpable(getClass().getSimpleName(), this);
    }

    /**
     * Tracks an instance that has a high leak risk (i.e. has complex ownership and references
     * a large amount of memory).
     *
     * The LeakDetector will monitor and keep weak references to such instances, dump statistics
     * about them in a bugreport, and in the future dump the heap if their count starts growing
     * unreasonably.
     *
     * This should be called when the instance is first constructed.
     */
    public  void trackInstance(T object) {
        if (mTrackedObjects != null) {
            mTrackedObjects.track(object);
        }
    }

    /**
     * Tracks a collection that is at risk of leaking large objects, e.g. a collection of
     * dynamically registered listeners.
     *
     * The LeakDetector will monitor and keep weak references to such collections, dump
     * statistics about them in a bugreport, and in the future dump the heap if their size starts
     * growing unreasonably.
     *
     * This should be called whenever the collection grows.
     *
     * @param tag A tag for labeling the collection in a bugreport
     */
    public  void trackCollection(Collection collection, String tag) {
        if (mTrackedCollections != null) {
            mTrackedCollections.track(collection, tag);
        }
    }

    /**
     * Tracks an instance that should become garbage soon.
     *
     * The LeakDetector will monitor and keep weak references to such garbage, dump
     * statistics about them in a bugreport, and in the future dump the heap if it is not
     * collected reasonably soon.
     *
     * This should be called when the last strong reference to the instance is dropped.
     */
    public void trackGarbage(Object o) {
        if (mTrackedGarbage != null) {
            mTrackedGarbage.track(o);
        }
    }

    TrackedGarbage getTrackedGarbage() {
        return mTrackedGarbage;
    }

    @Override
    public void dump(PrintWriter w, String[] args) {
        IndentingPrintWriter pw = new IndentingPrintWriter(w, "  ");

        pw.println("SYSUI LEAK DETECTOR");
        pw.increaseIndent();

        if (mTrackedCollections != null && mTrackedGarbage != null) {
            pw.println("TrackedCollections:");
            pw.increaseIndent();
            mTrackedCollections.dump(pw, (col) -> !TrackedObjects.isTrackedObject(col));
            pw.decreaseIndent();
            pw.println();

            pw.println("TrackedObjects:");
            pw.increaseIndent();
            mTrackedCollections.dump(pw, TrackedObjects::isTrackedObject);
            pw.decreaseIndent();
            pw.println();

            pw.print("TrackedGarbage:");
            pw.increaseIndent();
            mTrackedGarbage.dump(pw);
            pw.decreaseIndent();
        } else {
            pw.println("disabled");
        }
        pw.decreaseIndent();
        pw.println();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy