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

Commit 2cd3fb5a authored by Adam Lesinski's avatar Adam Lesinski
Browse files

Do not hold direct ref BatteryStatsImpl$Uid$Proc

BatteryStatsImpl can reset its collected data, including
removing a BatteryStatsImpl$Uid$Proc object. If a ProcessRecord
has a direct reference, then the battery stats for a process
will be recorded in an old Proc object and prevent GC, causing
a memory leak.

bug:11087238
Change-Id: I19a9cd9d8361c10446a8ebdd5c0860b56c442209
parent 2229ca03
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -2149,7 +2149,8 @@ public final class ActivityManagerService extends ActivityManagerNative
                                totalUTime += otherUTime;
                                totalSTime += otherSTime;
                                if (pr != null) {
                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
                                            st.name, st.pid);
                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
                                            st.rel_stime-otherSTime);
                                    ps.addSpeedStepTimes(cpuSpeedTimes);
@@ -2769,10 +2770,10 @@ public final class ActivityManagerService extends ActivityManagerNative
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, null);
            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
            synchronized (bs) {
                if (bs.isOnBattery()) {
                    app.batteryStats.incStartsLocked();
                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
                }
            }
@@ -8150,10 +8151,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
            }
        }
        synchronized (stats) {
            ps = stats.getProcessStatsLocked(info.uid, proc);
        }
        return new ProcessRecord(ps, info, proc, uid);
        return new ProcessRecord(stats, info, proc, uid);
    }
    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
+5 −5
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ import java.util.ArrayList;
 * is currently running.
 */
final class ProcessRecord {
    final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics
    private final BatteryStatsImpl mBatteryStats; // where to collect runtime statistics
    final ApplicationInfo info; // all about the first app in the process
    final boolean isolated;     // true if this is a special isolated process
    final int uid;              // uid of process; may be different from 'info' if isolated
@@ -273,8 +273,8 @@ final class ProcessRecord {
        }
        if (!keeping) {
            long wtime;
            synchronized (batteryStats.getBatteryStats()) {
                wtime = batteryStats.getBatteryStats().getProcessWakeTime(info.uid,
            synchronized (mBatteryStats) {
                wtime = mBatteryStats.getProcessWakeTime(info.uid,
                        pid, SystemClock.elapsedRealtime());
            }
            long timeUsed = wtime - lastWakeTime;
@@ -359,9 +359,9 @@ final class ProcessRecord {
        }
    }
    
    ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, ApplicationInfo _info,
    ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,
            String _processName, int _uid) {
        batteryStats = _batteryStats;
        mBatteryStats = _batteryStats;
        info = _info;
        isolated = _info.uid != _uid;
        uid = _uid;