Merge changes from topic "non-zygote"

* changes:
  Compact system processes.
  Compact persistent and BFGS processes.
This commit is contained in:
TreeHugger Robot
2019-03-22 13:58:23 +00:00
committed by Android (Google) Code Review
6 changed files with 233 additions and 27 deletions

View File

@@ -5121,6 +5121,7 @@ public class ActivityManagerService extends IActivityManager.Stub
String data, Bundle extras, boolean ordered,
boolean sticky, int sendingUser) {
synchronized (ActivityManagerService.this) {
mOomAdjuster.mAppCompact.compactAllSystem();
requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
}
}
@@ -8614,6 +8615,10 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (this) {
final long now = SystemClock.uptimeMillis();
final long timeSinceLastIdle = now - mLastIdleTime;
// Compact all non-zygote processes to freshen up the page cache.
mOomAdjuster.mAppCompact.compactAllSystem();
final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
mLastIdleTime = now;
mLowRamTimeSinceLastIdle = 0;

View File

@@ -51,6 +51,8 @@ public final class AppCompactor {
@VisibleForTesting static final String KEY_COMPACT_THROTTLE_2 = "compact_throttle_2";
@VisibleForTesting static final String KEY_COMPACT_THROTTLE_3 = "compact_throttle_3";
@VisibleForTesting static final String KEY_COMPACT_THROTTLE_4 = "compact_throttle_4";
@VisibleForTesting static final String KEY_COMPACT_THROTTLE_5 = "compact_throttle_5";
@VisibleForTesting static final String KEY_COMPACT_THROTTLE_6 = "compact_throttle_6";
@VisibleForTesting static final String KEY_COMPACT_STATSD_SAMPLE_RATE =
"compact_statsd_sample_rate";
@@ -73,6 +75,8 @@ public final class AppCompactor {
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_2 = 10_000;
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_3 = 500;
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_4 = 10_000;
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_5 = 10 * 60 * 1000;
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_6 = 10 * 60 * 1000;
// The sampling rate to push app compaction events into statsd for upload.
@VisibleForTesting static final float DEFAULT_STATSD_SAMPLE_RATE = 0.1f;
@@ -85,7 +89,10 @@ public final class AppCompactor {
// Handler constants.
static final int COMPACT_PROCESS_SOME = 1;
static final int COMPACT_PROCESS_FULL = 2;
static final int COMPACT_PROCESS_PERSISTENT = 3;
static final int COMPACT_PROCESS_BFGS = 4;
static final int COMPACT_PROCESS_MSG = 1;
static final int COMPACT_SYSTEM_MSG = 2;
/**
* This thread must be moved to the system background cpuset.
@@ -142,6 +149,10 @@ public final class AppCompactor {
@GuardedBy("mPhenotypeFlagLock")
@VisibleForTesting volatile long mCompactThrottleFullFull = DEFAULT_COMPACT_THROTTLE_4;
@GuardedBy("mPhenotypeFlagLock")
@VisibleForTesting volatile long mCompactThrottleBFGS = DEFAULT_COMPACT_THROTTLE_5;
@GuardedBy("mPhenotypeFlagLock")
@VisibleForTesting volatile long mCompactThrottlePersistent = DEFAULT_COMPACT_THROTTLE_6;
@GuardedBy("mPhenotypeFlagLock")
private volatile boolean mUseCompaction = DEFAULT_USE_COMPACTION;
private final Random mRandom = new Random();
@@ -224,6 +235,46 @@ public final class AppCompactor {
}
@GuardedBy("mAm")
void compactAppPersistent(ProcessRecord app) {
app.reqCompactAction = COMPACT_PROCESS_PERSISTENT;
mPendingCompactionProcesses.add(app);
mCompactionHandler.sendMessage(
mCompactionHandler.obtainMessage(
COMPACT_PROCESS_MSG, app.curAdj, app.setProcState));
}
@GuardedBy("mAm")
boolean shouldCompactPersistent(ProcessRecord app, long now) {
return (app.lastCompactTime == 0
|| (now - app.lastCompactTime) > mCompactThrottlePersistent);
}
@GuardedBy("mAm")
void compactAppBfgs(ProcessRecord app) {
app.reqCompactAction = COMPACT_PROCESS_BFGS;
mPendingCompactionProcesses.add(app);
mCompactionHandler.sendMessage(
mCompactionHandler.obtainMessage(
COMPACT_PROCESS_MSG, app.curAdj, app.setProcState));
}
@GuardedBy("mAm")
boolean shouldCompactBFGS(ProcessRecord app, long now) {
return (app.lastCompactTime == 0
|| (now - app.lastCompactTime) > mCompactThrottleBFGS);
}
@GuardedBy("mAm")
void compactAllSystem() {
if (mUseCompaction) {
mCompactionHandler.sendMessage(mCompactionHandler.obtainMessage(
COMPACT_SYSTEM_MSG));
}
}
private native void compactSystem();
/**
* Reads the flag value from DeviceConfig to determine whether app compaction
* should be enabled, and starts/stops the compaction thread as needed.
@@ -265,10 +316,18 @@ public final class AppCompactor {
String throttleFullFullFlag =
DeviceConfig.getProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_COMPACT_THROTTLE_4);
String throttleBFGSFlag =
DeviceConfig.getProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_COMPACT_THROTTLE_5);
String throttlePersistentFlag =
DeviceConfig.getProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_COMPACT_THROTTLE_6);
if (TextUtils.isEmpty(throttleSomeSomeFlag) || TextUtils.isEmpty(throttleSomeFullFlag)
|| TextUtils.isEmpty(throttleFullSomeFlag)
|| TextUtils.isEmpty(throttleFullFullFlag)) {
|| TextUtils.isEmpty(throttleFullFullFlag)
|| TextUtils.isEmpty(throttleBFGSFlag)
|| TextUtils.isEmpty(throttlePersistentFlag)) {
// Set defaults for all if any are not set.
useThrottleDefaults = true;
} else {
@@ -277,6 +336,8 @@ public final class AppCompactor {
mCompactThrottleSomeFull = Integer.parseInt(throttleSomeFullFlag);
mCompactThrottleFullSome = Integer.parseInt(throttleFullSomeFlag);
mCompactThrottleFullFull = Integer.parseInt(throttleFullFullFlag);
mCompactThrottleBFGS = Integer.parseInt(throttleBFGSFlag);
mCompactThrottlePersistent = Integer.parseInt(throttlePersistentFlag);
} catch (NumberFormatException e) {
useThrottleDefaults = true;
}
@@ -287,6 +348,8 @@ public final class AppCompactor {
mCompactThrottleSomeFull = DEFAULT_COMPACT_THROTTLE_2;
mCompactThrottleFullSome = DEFAULT_COMPACT_THROTTLE_3;
mCompactThrottleFullFull = DEFAULT_COMPACT_THROTTLE_4;
mCompactThrottleBFGS = DEFAULT_COMPACT_THROTTLE_5;
mCompactThrottlePersistent = DEFAULT_COMPACT_THROTTLE_6;
}
}
@@ -332,14 +395,19 @@ public final class AppCompactor {
synchronized (mAm) {
proc = mPendingCompactionProcesses.remove(0);
pendingAction = proc.reqCompactAction;
// don't compact if the process has returned to perceptible
if (proc.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
// and this is only a cached/home/prev compaction
if ((pendingAction == COMPACT_PROCESS_SOME
|| pendingAction == COMPACT_PROCESS_FULL)
&& (proc.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ)) {
return;
}
pid = proc.pid;
name = proc.processName;
pendingAction = proc.reqCompactAction;
lastCompactAction = proc.lastCompactAction;
lastCompactTime = proc.lastCompactTime;
}
@@ -356,31 +424,49 @@ public final class AppCompactor {
// Note that we explicitly don't take mPhenotypeFlagLock here as the flags
// should very seldom change, and taking the risk of using the wrong action is
// preferable to taking the lock for every single compaction action.
if (pendingAction == COMPACT_PROCESS_SOME) {
if ((lastCompactAction == COMPACT_PROCESS_SOME
&& (start - lastCompactTime < mCompactThrottleSomeSome))
|| (lastCompactAction == COMPACT_PROCESS_FULL
&& (start - lastCompactTime
< mCompactThrottleSomeFull))) {
return;
}
} else {
if ((lastCompactAction == COMPACT_PROCESS_SOME
&& (start - lastCompactTime < mCompactThrottleFullSome))
|| (lastCompactAction == COMPACT_PROCESS_FULL
&& (start - lastCompactTime
< mCompactThrottleFullFull))) {
return;
if (lastCompactTime != 0) {
if (pendingAction == COMPACT_PROCESS_SOME) {
if ((lastCompactAction == COMPACT_PROCESS_SOME
&& (start - lastCompactTime < mCompactThrottleSomeSome))
|| (lastCompactAction == COMPACT_PROCESS_FULL
&& (start - lastCompactTime
< mCompactThrottleSomeFull))) {
return;
}
} else if (pendingAction == COMPACT_PROCESS_FULL) {
if ((lastCompactAction == COMPACT_PROCESS_SOME
&& (start - lastCompactTime < mCompactThrottleFullSome))
|| (lastCompactAction == COMPACT_PROCESS_FULL
&& (start - lastCompactTime
< mCompactThrottleFullFull))) {
return;
}
} else if (pendingAction == COMPACT_PROCESS_PERSISTENT) {
if (start - lastCompactTime < mCompactThrottlePersistent) {
return;
}
} else if (pendingAction == COMPACT_PROCESS_BFGS) {
if (start - lastCompactTime < mCompactThrottleBFGS) {
return;
}
}
}
if (pendingAction == COMPACT_PROCESS_SOME) {
action = mCompactActionSome;
} else {
action = mCompactActionFull;
switch (pendingAction) {
case COMPACT_PROCESS_SOME:
action = mCompactActionSome;
break;
// For the time being, treat these as equivalent.
case COMPACT_PROCESS_FULL:
case COMPACT_PROCESS_PERSISTENT:
case COMPACT_PROCESS_BFGS:
action = mCompactActionFull;
break;
default:
action = COMPACT_ACTION_NONE;
break;
}
if (action.equals(COMPACT_ACTION_NONE)) {
if (COMPACT_ACTION_NONE.equals(action)) {
return;
}
@@ -422,6 +508,13 @@ public final class AppCompactor {
// nothing to do, presumably the process died
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break;
}
case COMPACT_SYSTEM_MSG: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactSystem");
compactSystem();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
}

View File

@@ -1686,9 +1686,10 @@ public final class OomAdjuster {
int changes = 0;
if (app.curAdj != app.setAdj) {
// don't compact during bootup
if (mAppCompact.useCompaction() && mService.mBooted) {
// don't compact during bootup
if (mAppCompact.useCompaction() && mService.mBooted) {
// Cached and prev/home compaction
if (app.curAdj != app.setAdj) {
// Perform a minor compaction when a perceptible app becomes the prev/home app
// Perform a major compaction when any app enters cached
// reminder: here, setAdj is previous state, curAdj is upcoming state
@@ -1702,7 +1703,23 @@ public final class OomAdjuster {
&& app.curAdj <= ProcessList.CACHED_APP_MAX_ADJ) {
mAppCompact.compactAppFull(app);
}
} else if (mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE
&& app.setAdj < ProcessList.FOREGROUND_APP_ADJ
// Because these can fire independent of oom_adj/procstate changes, we need
// to throttle the actual dispatch of these requests in addition to the
// processing of the requests. As a result, there is throttling both here
// and in AppCompactor.
&& mAppCompact.shouldCompactPersistent(app, now)) {
mAppCompact.compactAppPersistent(app);
} else if (mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE
&& app.getCurProcState()
== ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
&& mAppCompact.shouldCompactBFGS(app, now)) {
mAppCompact.compactAppBfgs(app);
}
}
if (app.curAdj != app.setAdj) {
ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) {
String msg = "Set " + app.pid + " " + app.processName + " adj "

View File

@@ -50,6 +50,7 @@ cc_library_static {
"com_android_server_VibratorService.cpp",
"com_android_server_PersistentDataBlockService.cpp",
"com_android_server_GraphicsStatsService.cpp",
"com_android_server_am_AppCompactor.cpp",
"onload.cpp",
],

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2019 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.
*/
#define LOG_TAG "AppCompactor"
//#define LOG_NDEBUG 0
#include <dirent.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <android-base/stringprintf.h>
#include <android-base/file.h>
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
#include <jni.h>
using android::base::StringPrintf;
using android::base::WriteStringToFile;
namespace android {
// This performs per-process reclaim on all processes belonging to non-app UIDs.
// For the most part, these are non-zygote processes like Treble HALs, but it
// also includes zygote-derived processes that run in system UIDs, like bluetooth
// or potentially some mainline modules. The only process that should definitely
// not be compacted is system_server, since compacting system_server around the
// time of BOOT_COMPLETE could result in perceptible issues.
static void com_android_server_am_AppCompactor_compactSystem(JNIEnv *, jobject) {
std::unique_ptr<DIR, decltype(&closedir)> proc(opendir("/proc"), closedir);
struct dirent* current;
while ((current = readdir(proc.get()))) {
if (current->d_type != DT_DIR) {
continue;
}
// don't compact system_server, rely on persistent compaction during screen off
// in order to avoid mmap_sem-related stalls
if (atoi(current->d_name) == getpid()) {
continue;
}
std::string status_name = StringPrintf("/proc/%s/status", current->d_name);
struct stat status_info;
if (stat(status_name.c_str(), &status_info) != 0) {
// must be some other directory that isn't a pid
continue;
}
// android.os.Process.FIRST_APPLICATION_UID
if (status_info.st_uid >= 10000) {
continue;
}
std::string reclaim_path = StringPrintf("/proc/%s/reclaim", current->d_name);
WriteStringToFile(std::string("all"), reclaim_path);
}
}
static const JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"compactSystem", "()V", (void*)com_android_server_am_AppCompactor_compactSystem},
};
int register_android_server_am_AppCompactor(JNIEnv* env)
{
return jniRegisterNativeMethods(env, "com/android/server/am/AppCompactor",
sMethods, NELEM(sMethods));
}
}

View File

@@ -54,6 +54,7 @@ int register_android_server_GraphicsStatsService(JNIEnv* env);
int register_android_hardware_display_DisplayViewport(JNIEnv* env);
int register_android_server_net_NetworkStatsService(JNIEnv* env);
int register_android_server_security_VerityUtils(JNIEnv* env);
int register_android_server_am_AppCompactor(JNIEnv* env);
};
using namespace android;
@@ -101,5 +102,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_hardware_display_DisplayViewport(env);
register_android_server_net_NetworkStatsService(env);
register_android_server_security_VerityUtils(env);
register_android_server_am_AppCompactor(env);
return JNI_VERSION_1_4;
}