Foreground GC和Background GC
ART运行时的Foreground GC和Background GC
它们是在ART运行时启动通过-Xgc和-XX:BackgroundGC指定的。但是在某同一段时间,ART运行时只会执行Foreground GC或者Background GC。也就是说,Foreground GC和Background GC在整个应用程序的生命周期中是交替执行的。这就涉及到从Foreground GC切换到Background GC,或者从Background GC切换到Foreground GC的问题。
应用程序的两个状态:kProcessStateJankPerceptible和kProcessStateJankImperceptible。其 中,kProcessStateJankPerceptible说的就是应用程序处于用户可感知的状态,这就相当于是前台状态;而 kProcessStateJankImperceptible说的就是应用程序处于用户不可感知的状态,这就相当于是后台状态。
class Heap { // The process state passed in from the activity manager, used to determine when to do trimming and compaction. enum ProcessState { kProcessStateJankPerceptible = 0, kProcessStateJankImperceptible = 1, }; }
这里是activity 启动时:
public final class ActivityThread { private class ApplicationThread extends ApplicationThreadNative { ...... public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord(); .................. sendMessage(H.LAUNCH_ACTIVITY, r); } 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); ...... } } }
public void setProcessState(int state) {
updateProcessState(state, true);
}
...... } ...... }
     每一个进程状态都通过一个整数来描述,其中,值越小就表示进程越重要。ART运行时将状态值大于等于PROCESS_STATE_IMPORTANT_FOREGROUND的进程都认为是用户可感知的,也就是前台进程,其余的进程则认为是用户不可感知的,也就是后台进程。通过这种方式,ApplicationThread类的成员函数updateProcessState就可以简化ART运行时对进程状态的处理。
       除了上述的Activity的Launch启动生命周期函数被ActivityManagerService通知调用时,Activity的Resume生命周期函数被ActivityManagerService通知调用调用时,也会发生类似的通过VMRuntime类的成员函数updateProcessState通知ART运行时应用程序状态发生了改变。对于其它的组件,例如Broadcast Receiver组件被触发时,Service组件被创建以及被绑定时,也会通过VMRuntime类的成员函数updateProcessState通知ART运行时应用程序状态发生了改变。
       不过,上述组件的生命周期对应的都是应用程序处于前台时的情况,也就是要求ART运行时从Background GC切换为Foreground GC的情况。当应用程序处于后台时,ActivityManagerService是通过直接设置应用程序的状态来通知ART运行时应用程序状态发生了改变的。
        ApplicationThread类实现了一个接口setProcessState,供ActivityManagerService直接设置应用程序的状态
public class ActivityManager { /** @hide Process is a persistent system process. */ public static final int PROCESS_STATE_PERSISTENT = 0; /** @hide Process is a persistent system process and is doing UI. */ public static final int PROCESS_STATE_PERSISTENT_UI = 1; /** @hide Process is hosting the current top activities. Note that this covers * all activities that are visible to the user. */ public static final int PROCESS_STATE_TOP = 2; /** @hide Process is hosting a foreground service due to a system binding. */ public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 3; /** @hide Process is hosting a foreground service. */ public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */ public static final int PROCESS_STATE_TOP_SLEEPING = 5; /** @hide Process is important to the user, and something they are aware of. */ public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6; /** @hide Process is important to the user, but not something they are aware of. */ public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7; /** @hide Process is in the background running a backup/restore operation. */ public static final int PROCESS_STATE_BACKUP = 8; /** @hide Process is in the background, but it can't restore its state so we want * to try to avoid killing it. */ public static final int PROCESS_STATE_HEAVY_WEIGHT = 9; /** @hide Process is in the background running a service. Unlike oom_adj, this level * is used for both the normal running in background state and the executing * operations state. */ public static final int PROCESS_STATE_SERVICE = 10; /** @hide Process is in the background running a receiver. Note that from the * perspective of oom_adj receivers run at a higher foreground level, but for our * prioritization here that is not necessary and putting them below services means * many fewer changes in some process states as they receive broadcasts. */ public static final int PROCESS_STATE_RECEIVER = 11; /** @hide Process is in the background but hosts the home activity. */ public static final int PROCESS_STATE_HOME = 12; /** @hide Process is in the background but hosts the last shown activity. */ public static final int PROCESS_STATE_LAST_ACTIVITY = 13; /** @hide Process is being cached for later use and contains activities. */ public static final int PROCESS_STATE_CACHED_ACTIVITY = 14; /** @hide Process is being cached for later use and is a client of another cached * process that contains activities. */ public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 15; /** @hide Process is being cached for later use and is empty. */ public static final int PROCESS_STATE_CACHED_EMPTY = 16; }
每一个进程状态都通过一个整数来描述,其中,值越小就表示进程越重要。ART运行时将状态值大于等于PROCESS_STATE_IMPORTANT_FOREGROUND的进程都认为是用户可感知的,也就是前台进程,其余的进程则认为是用户不可感知的,也就是后台进程。通过这种方式,ApplicationThread类的成员函数updateProcessState就可以简化ART运行时对进程状态的处理。
static void VMRuntime_updateProcessState(JNIEnv* env, jobject, jint process_state) { Runtime::Current()->GetHeap()->UpdateProcessState(static_cast<gc::ProcessState>(process_state)); ...... }
void Heap::UpdateProcessState(ProcessState process_state) { if (process_state_ != process_state) { process_state_ = process_state;if (process_state_ == kProcessStateJankPerceptible) { // Transition back to foreground right away to prevent jank. RequestCollectorTransition(foreground_collector_type_, 0); } else { // Don't delay for debug builds since we may want to stress test the GC. // If background_collector_type_ is kCollectorTypeHomogeneousSpaceCompact then we have // special handling which does a homogenous space compaction once but then doesn't transition // the collector. RequestCollectorTransition(background_collector_type_, kIsDebugBuild ? 0 : kCollectorTransitionWait); } } }
    如果是从kProcessStateJankImperceptible状态变为kProcessStateJankPerceptible状态,那么就调用Heap类的成员函数RequestCollectorTransition请求马上将当前的GC设置为Foreground GC。
    如果是从kProcessStateJankPerceptible状态变为kProcessStateJankImperceptible,那么就调用Heap类的成员函数RequestCollectorTransition请求将当前的GC设置为Background GC。注意,在这种情况下,对于非DEBUG版本的ART运行时,不是马上将当前的GC设置为Background GC的,而是指定在kCollectorTransitionWait(5秒)时间后再设置。这样使得进程进入后台运行的一小段时间内,仍然可以使用效率较高的Mark-Sweep GC。
                    
                
                
            
        
浙公网安备 33010602011771号