本文介紹AMS管理Activity時涉及到的重要的數(shù)據(jù)結(jié)構:
- ProcessRecord:安卓系統(tǒng)中用于描述進程的數(shù)據(jù)結(jié)構
- ActivityRecord:描述Activity的數(shù)據(jù)結(jié)構
- TaskRecord:描述棧的數(shù)據(jù)結(jié)構
ProcessRecord
AMS中的ProcessRecord成員變量
變量 | 意義 | 注釋 |
---|---|---|
mProcessNames |
數(shù)據(jù)類型為ProcessMap狸臣,以包名為key來記錄ProcessRecord; | All of the applications we currently have running organized by name.The keys are strings of the application package name (as returned by the package manager) |
mPidsSelfLocked |
數(shù)據(jù)類型為SparseArray昌执,以進程pid為key來記錄ProcessRecord | All of the processes we currently have running organized by pid. |
mLruProcesses |
以Lru排序的ArrayList<ProcessRecord> | List of running applications, sorted by recent usage. |
mRemovedProcesses | 數(shù)據(jù)類型為ArrayList,記錄所有需要強制移除的進程懂拾; | Processes that are being forcibly torn down. |
mProcessesToGc | 數(shù)據(jù)類型為ArrayList,記錄系統(tǒng)進入idle狀態(tài)需執(zhí)行gc操作的進程岖赋; | List of processes that should gc as soon as things are idle. |
mPendingPssProcesses | 數(shù)據(jù)類型為ArrayList,記錄將要收集內(nèi)存使用數(shù)據(jù)PSS 的進程选脊; |
Processes we want to collect PSS data from. |
mProcessesOnHold | 數(shù)據(jù)類型為ArrayList脸甘,記錄剛開機過程,系統(tǒng)還沒與偶準備就緒的情況下丹诀, 所有需要啟動的進程都放入到該隊列; | List of records for processes that someone had tried to start before the system was ready. We don't start them at that point, but ensure they are started by the time booting is complete. |
mPersistentStartingProcesses | 數(shù)據(jù)類型ArrayList硝桩,正在啟動的persistent進程 枚荣; |
List of persistent applications that are in the process of being started. |
mHomeProcess | 記錄包含home Activity所在的進程;應該是Launcher進程吧望薄,因為AMS開啟的第一個activity有一個方法叫getHomeIntent呼畸,我猜的
|
This is the process holding what we currently consider to be the "home" activity. |
mPreviousProcess | 上一次訪問的進程 | This is the process holding the activity the user last visited that is in a different process from the one they are currently in. |
因為每個人的翻譯不一樣,英文才能最準確的表達金毛的意思蛮原,所以我把注釋貼出來給大家參考;最重要的是前三個加紅的變量花嘶;
上面提到了進程的pss data,科普一下內(nèi)存相關的知識:
一般來說內(nèi)存占用大小有如下規(guī)律:VSS >= RSS >= PSS >= USS
VSS:
Virtual Set Size椭员,虛擬消耗內(nèi)存,其大小還包括了可能不在RAM中的內(nèi)存侍芝, VSS 很少被用于判斷一個進程的真實內(nèi)存使用量埋同。RSS:
Resident Set Size 實際使用物理內(nèi)存(包含共享庫的內(nèi)存),但是這個共享庫的內(nèi)存只會算一次凶赁,所以RSS也不是很準確PSS:
Proportional Set Size 實際使用的物理內(nèi)存(比例分配共享庫占用的內(nèi)存)虱肄,按比例分配共享庫的內(nèi)存,如果有三個進程都使用了一個共享庫浩峡,共占用了30頁內(nèi)存。那么PSS將認為每個進程分別占用該共享庫10頁的大小缕粹。 PSS是非常有用的數(shù)據(jù)纸淮,因為系統(tǒng)中所有進程的PSS都相加的話,就剛好反映了系統(tǒng)中的總共占用的內(nèi)存咽块。 而當一個進程被銷毀之后, 其占用的共享庫那部分比例的PSS揭璃,將會再次按比例分配給余下使用該庫的進程亭罪。USS:
Unique Set Size 進程獨自占用的物理內(nèi)存(不包含共享庫占用的內(nèi)存),USS是非常非常有用的數(shù)據(jù)应役,因為它反映了運行一個特定進程真實的邊際成本(增量成本)燥筷。當一個進程被銷毀后院崇,USS是真實返回給系統(tǒng)的內(nèi)存。當進程中存在一個可疑的內(nèi)存泄露時谢揪,USS是最佳觀察數(shù)據(jù)濒持。
persistent applications:
在manifest中配置的persistent屬性,這個屬性配置好了后會開機自啟柑营,在AMS的SystemReady
中會開啟所有的persistent為true的進程村视;
ProcessRecord中的成員變量
int pid; // The process of this application; 0 if none
final String processName; // name of the process
IApplicationThread thread; // the actual proc... may be null only if
// 'persistent' is true (in which case we
// are in the process of launching the app)
int maxAdj; // Maximum OOM adjustment for this process
int curRawAdj; // Current OOM unlimited adjustment for this process
int setRawAdj; // Last set OOM unlimited adjustment for this process
int curAdj; // Current OOM adjustment for this process
int setAdj; // Last set OOM adjustment for this process
int verifiedAdj; // The last adjustment that was verified as actually being set
// all activities running in the process
final ArrayList<ActivityRecord> activities = new ArrayList<>();
// any tasks this process had run root activities in
final ArrayList<TaskRecord> recentTasks = new ArrayList<>();
// all ServiceRecord running in this process
final ArraySet<ServiceRecord> services = new ArraySet<>();
// services that are currently executing code (need to remain foreground).
final ArraySet<ServiceRecord> executingServices = new ArraySet<>();
// All ConnectionRecord this process holds
final ArraySet<ConnectionRecord> connections = new ArraySet<>();
// all IIntentReceivers that are registered from this process.
final ArraySet<ReceiverList> receivers = new ArraySet<>();
// class (String) -> ContentProviderRecord
final ArrayMap<String, ContentProviderRecord> pubProviders = new ArrayMap<>();
// All ContentProviderRecord process is using
final ArrayList<ContentProviderConnection> conProviders = new ArrayList<>();
Dialog anrDialog; // dialog being displayed due to app not resp.
Dialog crashDialog; // dialog being displayed due to crash.
boolean killedByAm; // True when proc has been killed by activity manager, not for RAM
- pid:進程id
- processName :進程名奶赔,默認情況下進程名和該進程運行的第一個apk的包名是相同的杠氢,當然也可以自定義進程名;
- thread:IApplicationThread對象鼻百,上一篇文章中的app.thread,用于進程間通信温艇,通過attach綁定的;
-
adj:
adj可以理解為一個閾值晃琳,oom琐鲁,進程保活相關围段;內(nèi)存閾值吧,有時間仔細看
- 四大組件:運行在當前進程的四大組件
- anr彈框和crash彈框:后續(xù)我想總結(jié)一篇ANR相關的文章暴构;
- killedByAm:如果這個值為true,表示這個進程被ams殺了取逾,不是因為內(nèi)存不足
ActivityRecord
在AMS中,活動是以ActivityRecord的形式記錄的误阻,由ActivityStarter創(chuàng)建晴埂,關于ActivityStarter會在后面的文章中介紹,先看一下ActivityRecord記錄了哪些數(shù)據(jù):
final ActivityManagerService service; // owner
final Intent intent; // the original intent that generated us
final ActivityInfo info; // all about me
ProcessRecord app; // if non-null, hosting application
private TaskRecord task; // the task this is in.
final String launchedFromPackage; // always the package who started the activity.
final String taskAffinity; // as per ActivityInfo.taskAffinity
final ActivityStackSupervisor mStackSupervisor;
int launchMode; // the launch mode activity attribute.
private ActivityState mState; // current state we are in
- service:AMS的引用
- intent:開啟這個Activity的Intent
- info:ActivityInfo類精耐,包含了這個Activity的信息琅锻,包括Activity中的代碼,Manifest配置信息
- app:當前Activity所在的進程
- task:活動棧
- launchedFromPackage:Activity所在的包名
- taskAffinity:Activity希望歸屬的棧恼蓬,后面會仔細介紹這個參數(shù)
- mStackSupervisor:ActivityStackSupervisor引用,棧管理類
- launchMode:啟動模式
- mState:Activity的狀態(tài)
TaskRecord
final int taskId; // Unique identifier for this task.
String affinity; // The affinity name for this task, or null; may change identity.
Intent intent; // The original intent that started the task.
/** List of all activities in the task arranged in history order */
final ArrayList<ActivityRecord> mActivities;
/** Current stack. Setter must always be used to update the value. */
private ActivityStack mStack;
final ActivityManagerService mService;
- taskId:用來描述一個Activity任務棧
- affinity:棧的affinity小槐,可以在manifest為Activity指定affinity屬性表示活動希望歸屬的棧
- intent:開啟這個棧的intent
- mActivities:當前棧的Activity List
- mStack:當前棧對應的ActivityStack對象
- mService:AMS的引用
TaskRecord存儲了任務棧的所有信息荷辕,包括當前棧的活動List,棧的affinity屬性拄显,以及對應ActivityStack對象案站,下篇會詳細介紹ActivityStack以及AMS家族其他的成員;