Merge "Defer top process state for VM" into qt-dev

This commit is contained in:
TreeHugger Robot
2019-04-16 06:37:50 +00:00
committed by Android (Google) Code Review
3 changed files with 89 additions and 42 deletions

View File

@@ -16,6 +16,7 @@
package android.app;
import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
import static android.app.servertransaction.ActivityLifecycleItem.ON_CREATE;
import static android.app.servertransaction.ActivityLifecycleItem.ON_DESTROY;
import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE;
@@ -193,6 +194,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.TimeZone;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
final class RemoteServiceException extends AndroidRuntimeException {
public RemoteServiceException(String msg) {
@@ -224,6 +226,11 @@ public final class ActivityThread extends ClientTransactionHandler {
private static final boolean DEBUG_PROVIDER = false;
public static final boolean DEBUG_ORDER = false;
private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
/**
* If the activity doesn't become idle in time, the timeout will ensure to apply the pending top
* process state.
*/
private static final long PENDING_TOP_PROCESS_STATE_TIMEOUT = 1000;
/**
* The delay to release the provider when it has no more references. It reduces the number of
* transactions for acquiring and releasing provider if the client accesses the provider
@@ -242,6 +249,11 @@ public final class ActivityThread extends ClientTransactionHandler {
// Whether to invoke an activity callback after delivering new configuration.
private static final boolean REPORT_TO_ACTIVITY = true;
/** Use foreground GC policy (less pause time) and higher JIT weight. */
private static final int VM_PROCESS_STATE_JANK_PERCEPTIBLE = 0;
/** Use background GC policy and default JIT threshold. */
private static final int VM_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;
/**
* Denotes an invalid sequence number corresponding to a process state change.
*/
@@ -296,6 +308,11 @@ public final class ActivityThread extends ClientTransactionHandler {
// Number of activities that are currently visible on-screen.
@UnsupportedAppUsage
int mNumVisibleActivities = 0;
private final AtomicInteger mNumLaunchingActivities = new AtomicInteger();
@GuardedBy("mAppThread")
private int mLastProcessState = PROCESS_STATE_UNKNOWN;
@GuardedBy("mAppThread")
private int mPendingProcessState = PROCESS_STATE_UNKNOWN;
ArrayList<WeakReference<AssistStructure>> mLastAssistStructures = new ArrayList<>();
private int mLastSessionId;
@UnsupportedAppUsage
@@ -873,17 +890,6 @@ public final class ActivityThread extends ClientTransactionHandler {
private class ApplicationThread extends IApplicationThread.Stub {
private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
private int mLastProcessState = -1;
private void updatePendingConfiguration(Configuration config) {
synchronized (mResourcesManager) {
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(config)) {
mPendingConfiguration = config;
}
}
}
public final void scheduleSleeping(IBinder token, boolean sleeping) {
sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
}
@@ -1560,27 +1566,6 @@ public final class ActivityThread extends ClientTransactionHandler {
updateProcessState(state, true);
}
public void updateProcessState(int processState, boolean fromIpc) {
synchronized (this) {
if (mLastProcessState != processState) {
mLastProcessState = processState;
// Update Dalvik state based on ActivityManager.PROCESS_STATE_* constants.
final int DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE = 0;
final int DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;
int dalvikProcessState = DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE;
// TODO: Tune this since things like gmail sync are important background but not jank perceptible.
if (processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
dalvikProcessState = DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE;
}
VMRuntime.getRuntime().updateProcessState(dalvikProcessState);
if (false) {
Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
+ (fromIpc ? " (from ipc": ""));
}
}
}
}
/**
* Updates {@link #mNetworkBlockSeq}. This is used by ActivityManagerService to inform
* the main thread that it needs to wait for the network rules to get updated before
@@ -1661,16 +1646,6 @@ public final class ActivityThread extends ClientTransactionHandler {
}
}
@Override
public void updatePendingConfiguration(Configuration config) {
mAppThread.updatePendingConfiguration(config);
}
@Override
public void updateProcessState(int processState, boolean fromIpc) {
mAppThread.updateProcessState(processState, fromIpc);
}
class H extends Handler {
public static final int BIND_APPLICATION = 110;
@UnsupportedAppUsage
@@ -1995,6 +1970,7 @@ public final class ActivityThread extends ClientTransactionHandler {
if (stopProfiling) {
mProfiler.stopProfiling();
}
applyPendingProcessState();
return false;
}
}
@@ -2939,6 +2915,68 @@ public final class ActivityThread extends ClientTransactionHandler {
return mActivities.get(token);
}
@Override
public void updatePendingConfiguration(Configuration config) {
synchronized (mResourcesManager) {
if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(config)) {
mPendingConfiguration = config;
}
}
}
@Override
public void updateProcessState(int processState, boolean fromIpc) {
synchronized (mAppThread) {
if (mLastProcessState == processState) {
return;
}
mLastProcessState = processState;
// Defer the top state for VM to avoid aggressive JIT compilation affecting activity
// launch time.
if (processState == ActivityManager.PROCESS_STATE_TOP
&& mNumLaunchingActivities.get() > 0) {
mPendingProcessState = processState;
mH.postDelayed(this::applyPendingProcessState, PENDING_TOP_PROCESS_STATE_TIMEOUT);
} else {
mPendingProcessState = PROCESS_STATE_UNKNOWN;
updateVmProcessState(processState);
}
if (localLOGV) {
Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
+ (fromIpc ? " (from ipc" : ""));
}
}
}
/** Update VM state based on ActivityManager.PROCESS_STATE_* constants. */
private void updateVmProcessState(int processState) {
// TODO: Tune this since things like gmail sync are important background but not jank
// perceptible.
final int state = processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
? VM_PROCESS_STATE_JANK_PERCEPTIBLE
: VM_PROCESS_STATE_JANK_IMPERCEPTIBLE;
VMRuntime.getRuntime().updateProcessState(state);
}
private void applyPendingProcessState() {
synchronized (mAppThread) {
if (mPendingProcessState == PROCESS_STATE_UNKNOWN) {
return;
}
final int pendingState = mPendingProcessState;
mPendingProcessState = PROCESS_STATE_UNKNOWN;
// Only apply the pending state if the last state doesn't change.
if (pendingState == mLastProcessState) {
updateVmProcessState(pendingState);
}
}
}
@Override
public void countLaunchingActivities(int num) {
mNumLaunchingActivities.getAndAdd(num);
}
@UnsupportedAppUsage
public final void sendActivityResult(
IBinder token, String id, int requestCode,

View File

@@ -78,6 +78,8 @@ public abstract class ClientTransactionHandler {
/** Set current process state. */
public abstract void updateProcessState(int processState, boolean fromIpc);
/** Count how many activities are launching. */
public abstract void countLaunchingActivities(int num);
// Execute phase related logic and handlers. Methods here execute actual lifecycle transactions
// and deliver callbacks.

View File

@@ -66,6 +66,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
@Override
public void preExecute(ClientTransactionHandler client, IBinder token) {
client.countLaunchingActivities(1);
client.updateProcessState(mProcState, false);
client.updatePendingConfiguration(mCurConfig);
}
@@ -82,6 +83,12 @@ public class LaunchActivityItem extends ClientTransactionItem {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
client.countLaunchingActivities(-1);
}
// ObjectPoolItem implementation