Merge "Remove memory monitoring from the system watchdog" into gingerbread
This commit is contained in:
committed by
Android (Google) Code Review
commit
c8525edcba
@@ -1021,16 +1021,6 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case REPORT_PSS_TRANSACTION: {
|
|
||||||
data.enforceInterface(IActivityManager.descriptor);
|
|
||||||
IBinder b = data.readStrongBinder();
|
|
||||||
IApplicationThread app = ApplicationThreadNative.asInterface(b);
|
|
||||||
int pss = data.readInt();
|
|
||||||
reportPss(app, pss);
|
|
||||||
reply.writeNoException();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case START_RUNNING_TRANSACTION: {
|
case START_RUNNING_TRANSACTION: {
|
||||||
data.enforceInterface(IActivityManager.descriptor);
|
data.enforceInterface(IActivityManager.descriptor);
|
||||||
String pkg = data.readString();
|
String pkg = data.readString();
|
||||||
@@ -2529,14 +2519,6 @@ class ActivityManagerProxy implements IActivityManager
|
|||||||
reply.recycle();
|
reply.recycle();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
public void reportPss(IApplicationThread caller, int pss) throws RemoteException {
|
|
||||||
Parcel data = Parcel.obtain();
|
|
||||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
|
||||||
data.writeStrongBinder(caller.asBinder());
|
|
||||||
data.writeInt(pss);
|
|
||||||
mRemote.transact(REPORT_PSS_TRANSACTION, data, null, 0);
|
|
||||||
data.recycle();
|
|
||||||
}
|
|
||||||
public void startRunning(String pkg, String cls, String action,
|
public void startRunning(String pkg, String cls, String action,
|
||||||
String indata) throws RemoteException {
|
String indata) throws RemoteException {
|
||||||
Parcel data = Parcel.obtain();
|
Parcel data = Parcel.obtain();
|
||||||
|
|||||||
@@ -616,14 +616,6 @@ public final class ActivityThread {
|
|||||||
queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
|
queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestPss() {
|
|
||||||
try {
|
|
||||||
ActivityManagerNative.getDefault().reportPss(this,
|
|
||||||
(int)Process.getPss(Process.myPid()));
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void profilerControl(boolean start, String path, ParcelFileDescriptor fd) {
|
public void profilerControl(boolean start, String path, ParcelFileDescriptor fd) {
|
||||||
ProfilerControlData pcd = new ProfilerControlData();
|
ProfilerControlData pcd = new ProfilerControlData();
|
||||||
pcd.path = path;
|
pcd.path = path;
|
||||||
|
|||||||
@@ -341,13 +341,6 @@ public abstract class ApplicationThreadNative extends Binder
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case REQUEST_PSS_TRANSACTION:
|
|
||||||
{
|
|
||||||
data.enforceInterface(IApplicationThread.descriptor);
|
|
||||||
requestPss();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PROFILER_CONTROL_TRANSACTION:
|
case PROFILER_CONTROL_TRANSACTION:
|
||||||
{
|
{
|
||||||
data.enforceInterface(IApplicationThread.descriptor);
|
data.enforceInterface(IApplicationThread.descriptor);
|
||||||
@@ -779,14 +772,6 @@ class ApplicationThreadProxy implements IApplicationThread {
|
|||||||
data.recycle();
|
data.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void requestPss() throws RemoteException {
|
|
||||||
Parcel data = Parcel.obtain();
|
|
||||||
data.writeInterfaceToken(IApplicationThread.descriptor);
|
|
||||||
mRemote.transact(REQUEST_PSS_TRANSACTION, data, null,
|
|
||||||
IBinder.FLAG_ONEWAY);
|
|
||||||
data.recycle();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void profilerControl(boolean start, String path,
|
public void profilerControl(boolean start, String path,
|
||||||
ParcelFileDescriptor fd) throws RemoteException {
|
ParcelFileDescriptor fd) throws RemoteException {
|
||||||
Parcel data = Parcel.obtain();
|
Parcel data = Parcel.obtain();
|
||||||
|
|||||||
@@ -247,8 +247,6 @@ public interface IActivityManager extends IInterface {
|
|||||||
|
|
||||||
public boolean killPids(int[] pids, String reason) throws RemoteException;
|
public boolean killPids(int[] pids, String reason) throws RemoteException;
|
||||||
|
|
||||||
public void reportPss(IApplicationThread caller, int pss) throws RemoteException;
|
|
||||||
|
|
||||||
// Special low-level communication with activity manager.
|
// Special low-level communication with activity manager.
|
||||||
public void startRunning(String pkg, String cls, String action,
|
public void startRunning(String pkg, String cls, String action,
|
||||||
String data) throws RemoteException;
|
String data) throws RemoteException;
|
||||||
@@ -502,7 +500,7 @@ public interface IActivityManager extends IInterface {
|
|||||||
int FORCE_STOP_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+78;
|
int FORCE_STOP_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+78;
|
||||||
int KILL_PIDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+79;
|
int KILL_PIDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+79;
|
||||||
int GET_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+80;
|
int GET_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+80;
|
||||||
int REPORT_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+81;
|
|
||||||
int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82;
|
int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82;
|
||||||
int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
|
int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
|
||||||
int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
|
int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ public interface IApplicationThread extends IInterface {
|
|||||||
throws RemoteException;
|
throws RemoteException;
|
||||||
void scheduleLowMemory() throws RemoteException;
|
void scheduleLowMemory() throws RemoteException;
|
||||||
void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
|
void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
|
||||||
void requestPss() throws RemoteException;
|
|
||||||
void profilerControl(boolean start, String path, ParcelFileDescriptor fd)
|
void profilerControl(boolean start, String path, ParcelFileDescriptor fd)
|
||||||
throws RemoteException;
|
throws RemoteException;
|
||||||
void setSchedulingGroup(int group) throws RemoteException;
|
void setSchedulingGroup(int group) throws RemoteException;
|
||||||
@@ -132,7 +131,7 @@ public interface IApplicationThread extends IInterface {
|
|||||||
int SCHEDULE_LOW_MEMORY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+23;
|
int SCHEDULE_LOW_MEMORY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+23;
|
||||||
int SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+24;
|
int SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+24;
|
||||||
int SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+25;
|
int SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+25;
|
||||||
int REQUEST_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+26;
|
|
||||||
int PROFILER_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
|
int PROFILER_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
|
||||||
int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
|
int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
|
||||||
int SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
|
int SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
|
||||||
|
|||||||
@@ -57,20 +57,10 @@ public class Watchdog extends Thread {
|
|||||||
static final boolean RECORD_KERNEL_THREADS = true;
|
static final boolean RECORD_KERNEL_THREADS = true;
|
||||||
|
|
||||||
static final int MONITOR = 2718;
|
static final int MONITOR = 2718;
|
||||||
static final int GLOBAL_PSS = 2719;
|
|
||||||
|
|
||||||
static final int TIME_TO_RESTART = DB ? 15*1000 : 60*1000;
|
static final int TIME_TO_RESTART = DB ? 15*1000 : 60*1000;
|
||||||
static final int TIME_TO_WAIT = TIME_TO_RESTART / 2;
|
static final int TIME_TO_WAIT = TIME_TO_RESTART / 2;
|
||||||
|
|
||||||
static final int MEMCHECK_DEFAULT_INTERVAL = DB ? 30 : 30*60; // 30 minutes
|
|
||||||
static final int MEMCHECK_DEFAULT_LOG_REALTIME_INTERVAL = DB ? 60 : 2*60*60; // 2 hours
|
|
||||||
static final int MEMCHECK_DEFAULT_SYSTEM_SOFT_THRESHOLD = (DB ? 10:16)*1024*1024; // 16MB
|
|
||||||
static final int MEMCHECK_DEFAULT_SYSTEM_HARD_THRESHOLD = (DB ? 14:20)*1024*1024; // 20MB
|
|
||||||
static final int MEMCHECK_DEFAULT_PHONE_SOFT_THRESHOLD = (DB ? 4:8)*1024*1024; // 8MB
|
|
||||||
static final int MEMCHECK_DEFAULT_PHONE_HARD_THRESHOLD = (DB ? 8:12)*1024*1024; // 12MB
|
|
||||||
|
|
||||||
static final int MEMCHECK_DEFAULT_EXEC_START_TIME = 1*60*60; // 1:00am
|
|
||||||
static final int MEMCHECK_DEFAULT_EXEC_END_TIME = 5*60*60; // 5:00am
|
|
||||||
static final int MEMCHECK_DEFAULT_MIN_SCREEN_OFF = DB ? 1*60 : 5*60; // 5 minutes
|
static final int MEMCHECK_DEFAULT_MIN_SCREEN_OFF = DB ? 1*60 : 5*60; // 5 minutes
|
||||||
static final int MEMCHECK_DEFAULT_MIN_ALARM = DB ? 1*60 : 3*60; // 3 minutes
|
static final int MEMCHECK_DEFAULT_MIN_ALARM = DB ? 1*60 : 3*60; // 3 minutes
|
||||||
static final int MEMCHECK_DEFAULT_RECHECK_INTERVAL = DB ? 1*60 : 5*60; // 5 minutes
|
static final int MEMCHECK_DEFAULT_RECHECK_INTERVAL = DB ? 1*60 : 5*60; // 5 minutes
|
||||||
@@ -79,14 +69,12 @@ public class Watchdog extends Thread {
|
|||||||
static final int REBOOT_DEFAULT_START_TIME = 3*60*60; // 3:00am
|
static final int REBOOT_DEFAULT_START_TIME = 3*60*60; // 3:00am
|
||||||
static final int REBOOT_DEFAULT_WINDOW = 60*60; // within 1 hour
|
static final int REBOOT_DEFAULT_WINDOW = 60*60; // within 1 hour
|
||||||
|
|
||||||
static final String CHECKUP_ACTION = "com.android.service.Watchdog.CHECKUP";
|
|
||||||
static final String REBOOT_ACTION = "com.android.service.Watchdog.REBOOT";
|
static final String REBOOT_ACTION = "com.android.service.Watchdog.REBOOT";
|
||||||
|
|
||||||
static Watchdog sWatchdog;
|
static Watchdog sWatchdog;
|
||||||
|
|
||||||
/* This handler will be used to post message back onto the main thread */
|
/* This handler will be used to post message back onto the main thread */
|
||||||
final Handler mHandler;
|
final Handler mHandler;
|
||||||
final Runnable mGlobalPssCollected;
|
|
||||||
final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
|
final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
|
||||||
ContentResolver mResolver;
|
ContentResolver mResolver;
|
||||||
BatteryService mBattery;
|
BatteryService mBattery;
|
||||||
@@ -97,31 +85,9 @@ public class Watchdog extends Thread {
|
|||||||
boolean mForceKillSystem;
|
boolean mForceKillSystem;
|
||||||
Monitor mCurrentMonitor;
|
Monitor mCurrentMonitor;
|
||||||
|
|
||||||
PssRequestor mPhoneReq;
|
|
||||||
int mPhonePid;
|
int mPhonePid;
|
||||||
int mPhonePss;
|
|
||||||
|
|
||||||
long mLastMemCheckTime = -(MEMCHECK_DEFAULT_INTERVAL*1000);
|
|
||||||
boolean mHavePss;
|
|
||||||
long mLastMemCheckRealtime = -(MEMCHECK_DEFAULT_LOG_REALTIME_INTERVAL*1000);
|
|
||||||
boolean mHaveGlobalPss;
|
|
||||||
final MemMonitor mSystemMemMonitor = new MemMonitor("system",
|
|
||||||
Settings.Secure.MEMCHECK_SYSTEM_ENABLED,
|
|
||||||
Settings.Secure.MEMCHECK_SYSTEM_SOFT_THRESHOLD,
|
|
||||||
MEMCHECK_DEFAULT_SYSTEM_SOFT_THRESHOLD,
|
|
||||||
Settings.Secure.MEMCHECK_SYSTEM_HARD_THRESHOLD,
|
|
||||||
MEMCHECK_DEFAULT_SYSTEM_HARD_THRESHOLD);
|
|
||||||
final MemMonitor mPhoneMemMonitor = new MemMonitor("com.android.phone",
|
|
||||||
Settings.Secure.MEMCHECK_PHONE_ENABLED,
|
|
||||||
Settings.Secure.MEMCHECK_PHONE_SOFT_THRESHOLD,
|
|
||||||
MEMCHECK_DEFAULT_PHONE_SOFT_THRESHOLD,
|
|
||||||
Settings.Secure.MEMCHECK_PHONE_HARD_THRESHOLD,
|
|
||||||
MEMCHECK_DEFAULT_PHONE_HARD_THRESHOLD);
|
|
||||||
|
|
||||||
final Calendar mCalendar = Calendar.getInstance();
|
final Calendar mCalendar = Calendar.getInstance();
|
||||||
long mMemcheckLastTime;
|
|
||||||
long mMemcheckExecStartTime;
|
|
||||||
long mMemcheckExecEndTime;
|
|
||||||
int mMinScreenOff = MEMCHECK_DEFAULT_MIN_SCREEN_OFF;
|
int mMinScreenOff = MEMCHECK_DEFAULT_MIN_SCREEN_OFF;
|
||||||
int mMinAlarm = MEMCHECK_DEFAULT_MIN_ALARM;
|
int mMinAlarm = MEMCHECK_DEFAULT_MIN_ALARM;
|
||||||
boolean mNeedScheduledCheck;
|
boolean mNeedScheduledCheck;
|
||||||
@@ -139,93 +105,6 @@ public class Watchdog extends Thread {
|
|||||||
int mReqMinNextAlarm = -1; // >= 0 if specific time to next alarm has been requested
|
int mReqMinNextAlarm = -1; // >= 0 if specific time to next alarm has been requested
|
||||||
int mReqRecheckInterval= -1; // >= 0 if a specific recheck interval has been requested
|
int mReqRecheckInterval= -1; // >= 0 if a specific recheck interval has been requested
|
||||||
|
|
||||||
/**
|
|
||||||
* This class monitors the memory in a particular process.
|
|
||||||
*/
|
|
||||||
final class MemMonitor {
|
|
||||||
final String mProcessName;
|
|
||||||
final String mEnabledSetting;
|
|
||||||
final String mSoftSetting;
|
|
||||||
final String mHardSetting;
|
|
||||||
|
|
||||||
int mSoftThreshold;
|
|
||||||
int mHardThreshold;
|
|
||||||
boolean mEnabled;
|
|
||||||
long mLastPss;
|
|
||||||
|
|
||||||
static final int STATE_OK = 0;
|
|
||||||
static final int STATE_SOFT = 1;
|
|
||||||
static final int STATE_HARD = 2;
|
|
||||||
int mState;
|
|
||||||
|
|
||||||
MemMonitor(String processName, String enabledSetting,
|
|
||||||
String softSetting, int defSoftThreshold,
|
|
||||||
String hardSetting, int defHardThreshold) {
|
|
||||||
mProcessName = processName;
|
|
||||||
mEnabledSetting = enabledSetting;
|
|
||||||
mSoftSetting = softSetting;
|
|
||||||
mHardSetting = hardSetting;
|
|
||||||
mSoftThreshold = defSoftThreshold;
|
|
||||||
mHardThreshold = defHardThreshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
void retrieveSettings(ContentResolver resolver) {
|
|
||||||
mSoftThreshold = Settings.Secure.getInt(
|
|
||||||
resolver, mSoftSetting, mSoftThreshold);
|
|
||||||
mHardThreshold = Settings.Secure.getInt(
|
|
||||||
resolver, mHardSetting, mHardThreshold);
|
|
||||||
mEnabled = Settings.Secure.getInt(
|
|
||||||
resolver, mEnabledSetting, 0) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean checkLocked(long curTime, int pid, int pss) {
|
|
||||||
mLastPss = pss;
|
|
||||||
if (mLastPss < mSoftThreshold) {
|
|
||||||
mState = STATE_OK;
|
|
||||||
} else if (mLastPss < mHardThreshold) {
|
|
||||||
mState = STATE_SOFT;
|
|
||||||
} else {
|
|
||||||
mState = STATE_HARD;
|
|
||||||
}
|
|
||||||
EventLog.writeEvent(EventLogTags.WATCHDOG_PROC_PSS, mProcessName, pid, mLastPss);
|
|
||||||
|
|
||||||
if (mState == STATE_OK) {
|
|
||||||
// Memory is good, don't recover.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mState == STATE_HARD) {
|
|
||||||
// Memory is really bad, kill right now.
|
|
||||||
EventLog.writeEvent(EventLogTags.WATCHDOG_HARD_RESET, mProcessName, pid,
|
|
||||||
mHardThreshold, mLastPss);
|
|
||||||
return mEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is time to schedule a reset...
|
|
||||||
// Check if we are currently within the time to kill processes due
|
|
||||||
// to memory use.
|
|
||||||
computeMemcheckTimesLocked(curTime);
|
|
||||||
String skipReason = null;
|
|
||||||
if (curTime < mMemcheckExecStartTime || curTime > mMemcheckExecEndTime) {
|
|
||||||
skipReason = "time";
|
|
||||||
} else {
|
|
||||||
skipReason = shouldWeBeBrutalLocked(curTime);
|
|
||||||
}
|
|
||||||
EventLog.writeEvent(EventLogTags.WATCHDOG_SOFT_RESET, mProcessName, pid,
|
|
||||||
mSoftThreshold, mLastPss, skipReason != null ? skipReason : "");
|
|
||||||
if (skipReason != null) {
|
|
||||||
mNeedScheduledCheck = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return mEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
mLastPss = 0;
|
|
||||||
mState = STATE_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for scheduling monitor callbacks and checking memory usage.
|
* Used for scheduling monitor callbacks and checking memory usage.
|
||||||
*/
|
*/
|
||||||
@@ -233,33 +112,7 @@ public class Watchdog extends Thread {
|
|||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case GLOBAL_PSS: {
|
|
||||||
if (mHaveGlobalPss) {
|
|
||||||
// During the last pass we collected pss information, so
|
|
||||||
// now it is time to report it.
|
|
||||||
mHaveGlobalPss = false;
|
|
||||||
if (localLOGV) Slog.v(TAG, "Received global pss, logging.");
|
|
||||||
logGlobalMemory();
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case MONITOR: {
|
case MONITOR: {
|
||||||
if (mHavePss) {
|
|
||||||
// During the last pass we collected pss information, so
|
|
||||||
// now it is time to report it.
|
|
||||||
mHavePss = false;
|
|
||||||
if (localLOGV) Slog.v(TAG, "Have pss, checking memory.");
|
|
||||||
checkMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mHaveGlobalPss) {
|
|
||||||
// During the last pass we collected pss information, so
|
|
||||||
// now it is time to report it.
|
|
||||||
mHaveGlobalPss = false;
|
|
||||||
if (localLOGV) Slog.v(TAG, "Have global pss, logging.");
|
|
||||||
logGlobalMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
long now = SystemClock.uptimeMillis();
|
long now = SystemClock.uptimeMillis();
|
||||||
|
|
||||||
// See if we should force a reboot.
|
// See if we should force a reboot.
|
||||||
@@ -274,32 +127,6 @@ public class Watchdog extends Thread {
|
|||||||
checkReboot(false);
|
checkReboot(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we should check memory conditions.
|
|
||||||
long memCheckInterval = Settings.Secure.getLong(
|
|
||||||
mResolver, Settings.Secure.MEMCHECK_INTERVAL,
|
|
||||||
MEMCHECK_DEFAULT_INTERVAL) * 1000;
|
|
||||||
if ((mLastMemCheckTime+memCheckInterval) < now) {
|
|
||||||
// It is now time to collect pss information. This
|
|
||||||
// is async so we won't report it now. And to keep
|
|
||||||
// things simple, we will assume that everyone has
|
|
||||||
// reported back by the next MONITOR message.
|
|
||||||
mLastMemCheckTime = now;
|
|
||||||
if (localLOGV) Slog.v(TAG, "Collecting memory usage.");
|
|
||||||
collectMemory();
|
|
||||||
mHavePss = true;
|
|
||||||
|
|
||||||
long memCheckRealtimeInterval = Settings.Secure.getLong(
|
|
||||||
mResolver, Settings.Secure.MEMCHECK_LOG_REALTIME_INTERVAL,
|
|
||||||
MEMCHECK_DEFAULT_LOG_REALTIME_INTERVAL) * 1000;
|
|
||||||
long realtimeNow = SystemClock.elapsedRealtime();
|
|
||||||
if ((mLastMemCheckRealtime+memCheckRealtimeInterval) < realtimeNow) {
|
|
||||||
mLastMemCheckRealtime = realtimeNow;
|
|
||||||
if (localLOGV) Slog.v(TAG, "Collecting global memory usage.");
|
|
||||||
collectGlobalMemory();
|
|
||||||
mHaveGlobalPss = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final int size = mMonitors.size();
|
final int size = mMonitors.size();
|
||||||
for (int i = 0 ; i < size ; i++) {
|
for (int i = 0 ; i < size ; i++) {
|
||||||
mCurrentMonitor = mMonitors.get(i);
|
mCurrentMonitor = mMonitors.get(i);
|
||||||
@@ -315,20 +142,6 @@ public class Watchdog extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class GlobalPssCollected implements Runnable {
|
|
||||||
public void run() {
|
|
||||||
mHandler.sendEmptyMessage(GLOBAL_PSS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class CheckupReceiver extends BroadcastReceiver {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context c, Intent intent) {
|
|
||||||
if (localLOGV) Slog.v(TAG, "Alarm went off, checking memory.");
|
|
||||||
checkMemory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class RebootReceiver extends BroadcastReceiver {
|
final class RebootReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context c, Intent intent) {
|
public void onReceive(Context c, Intent intent) {
|
||||||
@@ -359,27 +172,6 @@ public class Watchdog extends Thread {
|
|||||||
void monitor();
|
void monitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface PssRequestor {
|
|
||||||
void requestPss();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PssStats {
|
|
||||||
public int mEmptyPss;
|
|
||||||
public int mEmptyCount;
|
|
||||||
public int mBackgroundPss;
|
|
||||||
public int mBackgroundCount;
|
|
||||||
public int mServicePss;
|
|
||||||
public int mServiceCount;
|
|
||||||
public int mVisiblePss;
|
|
||||||
public int mVisibleCount;
|
|
||||||
public int mForegroundPss;
|
|
||||||
public int mForegroundCount;
|
|
||||||
|
|
||||||
public int mNoPssCount;
|
|
||||||
|
|
||||||
public int mProcDeaths[] = new int[10];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Watchdog getInstance() {
|
public static Watchdog getInstance() {
|
||||||
if (sWatchdog == null) {
|
if (sWatchdog == null) {
|
||||||
sWatchdog = new Watchdog();
|
sWatchdog = new Watchdog();
|
||||||
@@ -391,7 +183,6 @@ public class Watchdog extends Thread {
|
|||||||
private Watchdog() {
|
private Watchdog() {
|
||||||
super("watchdog");
|
super("watchdog");
|
||||||
mHandler = new HeartbeatHandler();
|
mHandler = new HeartbeatHandler();
|
||||||
mGlobalPssCollected = new GlobalPssCollected();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(Context context, BatteryService battery,
|
public void init(Context context, BatteryService battery,
|
||||||
@@ -403,11 +194,6 @@ public class Watchdog extends Thread {
|
|||||||
mAlarm = alarm;
|
mAlarm = alarm;
|
||||||
mActivity = activity;
|
mActivity = activity;
|
||||||
|
|
||||||
context.registerReceiver(new CheckupReceiver(),
|
|
||||||
new IntentFilter(CHECKUP_ACTION));
|
|
||||||
mCheckupIntent = PendingIntent.getBroadcast(context,
|
|
||||||
0, new Intent(CHECKUP_ACTION), 0);
|
|
||||||
|
|
||||||
context.registerReceiver(new RebootReceiver(),
|
context.registerReceiver(new RebootReceiver(),
|
||||||
new IntentFilter(REBOOT_ACTION));
|
new IntentFilter(REBOOT_ACTION));
|
||||||
mRebootIntent = PendingIntent.getBroadcast(context,
|
mRebootIntent = PendingIntent.getBroadcast(context,
|
||||||
@@ -420,20 +206,10 @@ public class Watchdog extends Thread {
|
|||||||
mBootTime = System.currentTimeMillis();
|
mBootTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processStarted(PssRequestor req, String name, int pid) {
|
public void processStarted(String name, int pid) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if ("com.android.phone".equals(name)) {
|
if ("com.android.phone".equals(name)) {
|
||||||
mPhoneReq = req;
|
|
||||||
mPhonePid = pid;
|
mPhonePid = pid;
|
||||||
mPhonePss = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reportPss(PssRequestor req, String name, int pss) {
|
|
||||||
synchronized (this) {
|
|
||||||
if (mPhoneReq == req) {
|
|
||||||
mPhonePss = pss;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -447,152 +223,6 @@ public class Watchdog extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve memory usage information from specific processes being
|
|
||||||
* monitored. This is an async operation, so must be done before doing
|
|
||||||
* memory checks.
|
|
||||||
*/
|
|
||||||
void collectMemory() {
|
|
||||||
synchronized (this) {
|
|
||||||
if (mPhoneReq != null) {
|
|
||||||
mPhoneReq.requestPss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve memory usage over all application processes. This is an
|
|
||||||
* async operation, so must be done before doing memory checks.
|
|
||||||
*/
|
|
||||||
void collectGlobalMemory() {
|
|
||||||
mActivity.requestPss(mGlobalPssCollected);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check memory usage in the system, scheduling kills/reboots as needed.
|
|
||||||
* This always runs on the mHandler thread.
|
|
||||||
*/
|
|
||||||
void checkMemory() {
|
|
||||||
boolean needScheduledCheck;
|
|
||||||
long curTime;
|
|
||||||
long nextTime = 0;
|
|
||||||
|
|
||||||
long recheckInterval = Settings.Secure.getLong(
|
|
||||||
mResolver, Settings.Secure.MEMCHECK_RECHECK_INTERVAL,
|
|
||||||
MEMCHECK_DEFAULT_RECHECK_INTERVAL) * 1000;
|
|
||||||
|
|
||||||
mSystemMemMonitor.retrieveSettings(mResolver);
|
|
||||||
mPhoneMemMonitor.retrieveSettings(mResolver);
|
|
||||||
retrieveBrutalityAmount();
|
|
||||||
|
|
||||||
synchronized (this) {
|
|
||||||
curTime = System.currentTimeMillis();
|
|
||||||
mNeedScheduledCheck = false;
|
|
||||||
|
|
||||||
// How is the system doing?
|
|
||||||
if (mSystemMemMonitor.checkLocked(curTime, Process.myPid(),
|
|
||||||
(int)Process.getPss(Process.myPid()))) {
|
|
||||||
// Not good! Time to suicide.
|
|
||||||
mForceKillSystem = true;
|
|
||||||
notifyAll();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// How is the phone process doing?
|
|
||||||
if (mPhoneReq != null) {
|
|
||||||
if (mPhoneMemMonitor.checkLocked(curTime, mPhonePid,
|
|
||||||
mPhonePss)) {
|
|
||||||
// Just kill the phone process and let it restart.
|
|
||||||
Slog.i(TAG, "Watchdog is killing the phone process");
|
|
||||||
Process.killProcess(mPhonePid);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mPhoneMemMonitor.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
needScheduledCheck = mNeedScheduledCheck;
|
|
||||||
if (needScheduledCheck) {
|
|
||||||
// Something is going bad, but now is not a good time to
|
|
||||||
// tear things down... schedule an alarm to check again soon.
|
|
||||||
nextTime = curTime + recheckInterval;
|
|
||||||
if (nextTime < mMemcheckExecStartTime) {
|
|
||||||
nextTime = mMemcheckExecStartTime;
|
|
||||||
} else if (nextTime >= mMemcheckExecEndTime){
|
|
||||||
// Need to check during next exec time... so that needs
|
|
||||||
// to be computed.
|
|
||||||
if (localLOGV) Slog.v(TAG, "Computing next time range");
|
|
||||||
computeMemcheckTimesLocked(nextTime);
|
|
||||||
nextTime = mMemcheckExecStartTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (localLOGV) {
|
|
||||||
mCalendar.setTimeInMillis(nextTime);
|
|
||||||
Slog.v(TAG, "Next Alarm Time: " + mCalendar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needScheduledCheck) {
|
|
||||||
if (localLOGV) Slog.v(TAG, "Scheduling next memcheck alarm for "
|
|
||||||
+ ((nextTime-curTime)/1000/60) + "m from now");
|
|
||||||
mAlarm.remove(mCheckupIntent);
|
|
||||||
mAlarm.set(AlarmManager.RTC_WAKEUP, nextTime, mCheckupIntent);
|
|
||||||
} else {
|
|
||||||
if (localLOGV) Slog.v(TAG, "No need to schedule a memcheck alarm!");
|
|
||||||
mAlarm.remove(mCheckupIntent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final PssStats mPssStats = new PssStats();
|
|
||||||
final String[] mMemInfoFields = new String[] {
|
|
||||||
"MemFree:", "Buffers:", "Cached:",
|
|
||||||
"Active:", "Inactive:",
|
|
||||||
"AnonPages:", "Mapped:", "Slab:",
|
|
||||||
"SReclaimable:", "SUnreclaim:", "PageTables:" };
|
|
||||||
final long[] mMemInfoSizes = new long[mMemInfoFields.length];
|
|
||||||
final String[] mVMStatFields = new String[] {
|
|
||||||
"pgfree ", "pgactivate ", "pgdeactivate ",
|
|
||||||
"pgfault ", "pgmajfault " };
|
|
||||||
final long[] mVMStatSizes = new long[mVMStatFields.length];
|
|
||||||
final long[] mPrevVMStatSizes = new long[mVMStatFields.length];
|
|
||||||
long mLastLogGlobalMemoryTime;
|
|
||||||
|
|
||||||
void logGlobalMemory() {
|
|
||||||
PssStats stats = mPssStats;
|
|
||||||
mActivity.collectPss(stats);
|
|
||||||
EventLog.writeEvent(EventLogTags.WATCHDOG_PSS_STATS,
|
|
||||||
stats.mEmptyPss, stats.mEmptyCount,
|
|
||||||
stats.mBackgroundPss, stats.mBackgroundCount,
|
|
||||||
stats.mServicePss, stats.mServiceCount,
|
|
||||||
stats.mVisiblePss, stats.mVisibleCount,
|
|
||||||
stats.mForegroundPss, stats.mForegroundCount,
|
|
||||||
stats.mNoPssCount);
|
|
||||||
EventLog.writeEvent(EventLogTags.WATCHDOG_PROC_STATS,
|
|
||||||
stats.mProcDeaths[0], stats.mProcDeaths[1], stats.mProcDeaths[2],
|
|
||||||
stats.mProcDeaths[3], stats.mProcDeaths[4]);
|
|
||||||
Process.readProcLines("/proc/meminfo", mMemInfoFields, mMemInfoSizes);
|
|
||||||
for (int i=0; i<mMemInfoSizes.length; i++) {
|
|
||||||
mMemInfoSizes[i] *= 1024;
|
|
||||||
}
|
|
||||||
EventLog.writeEvent(EventLogTags.WATCHDOG_MEMINFO,
|
|
||||||
(int)mMemInfoSizes[0], (int)mMemInfoSizes[1], (int)mMemInfoSizes[2],
|
|
||||||
(int)mMemInfoSizes[3], (int)mMemInfoSizes[4],
|
|
||||||
(int)mMemInfoSizes[5], (int)mMemInfoSizes[6], (int)mMemInfoSizes[7],
|
|
||||||
(int)mMemInfoSizes[8], (int)mMemInfoSizes[9], (int)mMemInfoSizes[10]);
|
|
||||||
long now = SystemClock.uptimeMillis();
|
|
||||||
long dur = now - mLastLogGlobalMemoryTime;
|
|
||||||
mLastLogGlobalMemoryTime = now;
|
|
||||||
Process.readProcLines("/proc/vmstat", mVMStatFields, mVMStatSizes);
|
|
||||||
for (int i=0; i<mVMStatSizes.length; i++) {
|
|
||||||
long v = mVMStatSizes[i];
|
|
||||||
mVMStatSizes[i] -= mPrevVMStatSizes[i];
|
|
||||||
mPrevVMStatSizes[i] = v;
|
|
||||||
}
|
|
||||||
EventLog.writeEvent(EventLogTags.WATCHDOG_VMSTAT, dur,
|
|
||||||
(int)mVMStatSizes[0], (int)mVMStatSizes[1], (int)mVMStatSizes[2],
|
|
||||||
(int)mVMStatSizes[3], (int)mVMStatSizes[4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkReboot(boolean fromAlarm) {
|
void checkReboot(boolean fromAlarm) {
|
||||||
int rebootInterval = mReqRebootInterval >= 0 ? mReqRebootInterval
|
int rebootInterval = mReqRebootInterval >= 0 ? mReqRebootInterval
|
||||||
: Settings.Secure.getInt(
|
: Settings.Secure.getInt(
|
||||||
@@ -730,47 +360,6 @@ public class Watchdog extends Thread {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute the times during which we next would like to perform process
|
|
||||||
* restarts.
|
|
||||||
*
|
|
||||||
* @param curTime The current system time.
|
|
||||||
*/
|
|
||||||
void computeMemcheckTimesLocked(long curTime) {
|
|
||||||
if (mMemcheckLastTime == curTime) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mMemcheckLastTime = curTime;
|
|
||||||
|
|
||||||
long memcheckExecStartTime = Settings.Secure.getLong(
|
|
||||||
mResolver, Settings.Secure.MEMCHECK_EXEC_START_TIME,
|
|
||||||
MEMCHECK_DEFAULT_EXEC_START_TIME);
|
|
||||||
long memcheckExecEndTime = Settings.Secure.getLong(
|
|
||||||
mResolver, Settings.Secure.MEMCHECK_EXEC_END_TIME,
|
|
||||||
MEMCHECK_DEFAULT_EXEC_END_TIME);
|
|
||||||
|
|
||||||
mMemcheckExecEndTime = computeCalendarTime(mCalendar, curTime,
|
|
||||||
memcheckExecEndTime);
|
|
||||||
if (mMemcheckExecEndTime < curTime) {
|
|
||||||
memcheckExecStartTime += 24*60*60;
|
|
||||||
memcheckExecEndTime += 24*60*60;
|
|
||||||
mMemcheckExecEndTime = computeCalendarTime(mCalendar, curTime,
|
|
||||||
memcheckExecEndTime);
|
|
||||||
}
|
|
||||||
mMemcheckExecStartTime = computeCalendarTime(mCalendar, curTime,
|
|
||||||
memcheckExecStartTime);
|
|
||||||
|
|
||||||
if (localLOGV) {
|
|
||||||
mCalendar.setTimeInMillis(curTime);
|
|
||||||
Slog.v(TAG, "Current Time: " + mCalendar);
|
|
||||||
mCalendar.setTimeInMillis(mMemcheckExecStartTime);
|
|
||||||
Slog.v(TAG, "Start Check Time: " + mCalendar);
|
|
||||||
mCalendar.setTimeInMillis(mMemcheckExecEndTime);
|
|
||||||
Slog.v(TAG, "End Check Time: " + mCalendar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static long computeCalendarTime(Calendar c, long curTime,
|
static long computeCalendarTime(Calendar c, long curTime,
|
||||||
long secondsSinceMidnight) {
|
long secondsSinceMidnight) {
|
||||||
|
|
||||||
|
|||||||
@@ -880,7 +880,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
if (localLOGV) Slog.v(
|
if (localLOGV) Slog.v(
|
||||||
TAG, "Death received in " + this
|
TAG, "Death received in " + this
|
||||||
+ " for thread " + mAppThread.asBinder());
|
+ " for thread " + mAppThread.asBinder());
|
||||||
removeRequestedPss(mApp);
|
|
||||||
synchronized(ActivityManagerService.this) {
|
synchronized(ActivityManagerService.this) {
|
||||||
appDiedLocked(mApp, mPid, mAppThread);
|
appDiedLocked(mApp, mPid, mAppThread);
|
||||||
}
|
}
|
||||||
@@ -1785,7 +1784,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
hostingNameStr != null ? hostingNameStr : "");
|
hostingNameStr != null ? hostingNameStr : "");
|
||||||
|
|
||||||
if (app.persistent) {
|
if (app.persistent) {
|
||||||
Watchdog.getInstance().processStarted(app, app.processName, pid);
|
Watchdog.getInstance().processStarted(app.processName, pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder buf = mStringBuilder;
|
StringBuilder buf = mStringBuilder;
|
||||||
@@ -5662,123 +5661,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
return killed;
|
return killed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reportPss(IApplicationThread caller, int pss) {
|
|
||||||
Watchdog.PssRequestor req;
|
|
||||||
String name;
|
|
||||||
ProcessRecord callerApp;
|
|
||||||
synchronized (this) {
|
|
||||||
if (caller == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callerApp = getRecordForAppLocked(caller);
|
|
||||||
if (callerApp == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callerApp.lastPss = pss;
|
|
||||||
req = callerApp;
|
|
||||||
name = callerApp.processName;
|
|
||||||
}
|
|
||||||
Watchdog.getInstance().reportPss(req, name, pss);
|
|
||||||
if (!callerApp.persistent) {
|
|
||||||
removeRequestedPss(callerApp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void requestPss(Runnable completeCallback) {
|
|
||||||
ArrayList<ProcessRecord> procs;
|
|
||||||
synchronized (this) {
|
|
||||||
mRequestPssCallback = completeCallback;
|
|
||||||
mRequestPssList.clear();
|
|
||||||
for (int i=mLruProcesses.size()-1; i>=0; i--) {
|
|
||||||
ProcessRecord proc = mLruProcesses.get(i);
|
|
||||||
if (!proc.persistent) {
|
|
||||||
mRequestPssList.add(proc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
procs = new ArrayList<ProcessRecord>(mRequestPssList);
|
|
||||||
}
|
|
||||||
|
|
||||||
int oldPri = Process.getThreadPriority(Process.myTid());
|
|
||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
|
||||||
for (int i=procs.size()-1; i>=0; i--) {
|
|
||||||
ProcessRecord proc = procs.get(i);
|
|
||||||
proc.lastPss = 0;
|
|
||||||
proc.requestPss();
|
|
||||||
}
|
|
||||||
Process.setThreadPriority(oldPri);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeRequestedPss(ProcessRecord proc) {
|
|
||||||
Runnable callback = null;
|
|
||||||
synchronized (this) {
|
|
||||||
if (mRequestPssList.remove(proc)) {
|
|
||||||
if (mRequestPssList.size() == 0) {
|
|
||||||
callback = mRequestPssCallback;
|
|
||||||
mRequestPssCallback = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callback != null) {
|
|
||||||
callback.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void collectPss(Watchdog.PssStats stats) {
|
|
||||||
stats.mEmptyPss = 0;
|
|
||||||
stats.mEmptyCount = 0;
|
|
||||||
stats.mBackgroundPss = 0;
|
|
||||||
stats.mBackgroundCount = 0;
|
|
||||||
stats.mServicePss = 0;
|
|
||||||
stats.mServiceCount = 0;
|
|
||||||
stats.mVisiblePss = 0;
|
|
||||||
stats.mVisibleCount = 0;
|
|
||||||
stats.mForegroundPss = 0;
|
|
||||||
stats.mForegroundCount = 0;
|
|
||||||
stats.mNoPssCount = 0;
|
|
||||||
synchronized (this) {
|
|
||||||
int i;
|
|
||||||
int NPD = mProcDeaths.length < stats.mProcDeaths.length
|
|
||||||
? mProcDeaths.length : stats.mProcDeaths.length;
|
|
||||||
int aggr = 0;
|
|
||||||
for (i=0; i<NPD; i++) {
|
|
||||||
aggr += mProcDeaths[i];
|
|
||||||
stats.mProcDeaths[i] = aggr;
|
|
||||||
}
|
|
||||||
while (i<stats.mProcDeaths.length) {
|
|
||||||
stats.mProcDeaths[i] = 0;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=mLruProcesses.size()-1; i>=0; i--) {
|
|
||||||
ProcessRecord proc = mLruProcesses.get(i);
|
|
||||||
if (proc.persistent) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//Slog.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss);
|
|
||||||
if (proc.lastPss == 0) {
|
|
||||||
stats.mNoPssCount++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) {
|
|
||||||
if (proc.empty) {
|
|
||||||
stats.mEmptyPss += proc.lastPss;
|
|
||||||
stats.mEmptyCount++;
|
|
||||||
} else {
|
|
||||||
stats.mBackgroundPss += proc.lastPss;
|
|
||||||
stats.mBackgroundCount++;
|
|
||||||
}
|
|
||||||
} else if (proc.setAdj >= VISIBLE_APP_ADJ) {
|
|
||||||
stats.mVisiblePss += proc.lastPss;
|
|
||||||
stats.mVisibleCount++;
|
|
||||||
} else {
|
|
||||||
stats.mForegroundPss += proc.lastPss;
|
|
||||||
stats.mForegroundCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void startRunning(String pkg, String cls, String action,
|
public final void startRunning(String pkg, String cls, String action,
|
||||||
String data) {
|
String data) {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import java.util.HashSet;
|
|||||||
* Full information about a particular process that
|
* Full information about a particular process that
|
||||||
* is currently running.
|
* is currently running.
|
||||||
*/
|
*/
|
||||||
class ProcessRecord implements Watchdog.PssRequestor {
|
class ProcessRecord {
|
||||||
final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics
|
final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics
|
||||||
final ApplicationInfo info; // all about the first app in the process
|
final ApplicationInfo info; // all about the first app in the process
|
||||||
final String processName; // name of the process
|
final String processName; // name of the process
|
||||||
@@ -264,16 +264,6 @@ class ProcessRecord implements Watchdog.PssRequestor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestPss() {
|
|
||||||
IApplicationThread localThread = thread;
|
|
||||||
if (localThread != null) {
|
|
||||||
try {
|
|
||||||
localThread.requestPss();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
if (shortStringName != null) {
|
if (shortStringName != null) {
|
||||||
return shortStringName;
|
return shortStringName;
|
||||||
|
|||||||
Reference in New Issue
Block a user