Merge "Defer top process state for VM" into qt-dev
am: e6b9bdf4d0
Change-Id: I1d9d698345e1c53ea9f9c96fb49130d0b040f4b9
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user