欧美日韩不卡一区二区三区,www.蜜臀.com,高清国产一区二区三区四区五区,欧美日韩三级视频,欧美性综合,精品国产91久久久久久,99a精品视频在线观看

操作系統(tǒng)

Android操作系統(tǒng)的內(nèi)存回收的策略是什么

時間:2024-12-18 22:23:39 操作系統(tǒng) 我要投稿
  • 相關(guān)推薦

Android操作系統(tǒng)的內(nèi)存回收的策略是什么

  Android 是一款基于 Linux 內(nèi)核,面向移動終端的操作系統(tǒng)。為適應(yīng)其作為移動平臺操作系統(tǒng)的特殊需要,谷歌對其做了特別的設(shè)計與優(yōu)化,使應(yīng)用程序關(guān)閉但不退出,并由操作系統(tǒng)進行進程的回收管理。本文在 Application Framework 與 Linux 內(nèi)核兩個層次上,以進程為粒度,對 Android 操作系統(tǒng)的進程資源回收機制進行了剖析。讀者可以從本文獲得對 Android 應(yīng)用程序的生存周期的進一步理解,從而更加合理、高效地構(gòu)建應(yīng)用程序。

  Android 操作系統(tǒng)中的內(nèi)存回收可分為兩個層次:

  1、默認(rèn)內(nèi)存回收、即Application Framework 層的默認(rèn)回收。

  2、內(nèi)核級內(nèi)存回收。

  Linux 內(nèi)核中的內(nèi)存回收 lowmemorykiller、OOM_killer。

  默認(rèn)內(nèi)存回收:(代碼可查閱 ActivityManagerService.java類)回收動作入口activityIdleInternal()。

  Android 系統(tǒng)中內(nèi)存回收的觸發(fā)點大致可分為三種情況。

  第一,用戶程序調(diào)用 StartActivity(), 使當(dāng)前活動的 Activity 被覆蓋;

  第二,用戶按 back 鍵,退出當(dāng)前應(yīng)用程序;第三,啟動一個新的應(yīng)用程序。

  這些能夠觸發(fā)內(nèi)存回收的事件最終調(diào)用的函數(shù)接口就是 activityIdleInternal()。當(dāng) ActivityManagerService 接收到異步消息 IDLE_TIMEOUT_MSG 或者 IDLE_NOW_MSG 時,activityIdleInternal() 將會被調(diào)用。 IDLE_NOW_MSG 由 Activity 的切換以及 Activiy 焦點的改變等事件引發(fā),IDLE_TIMEOUT_MSG 在 Activity 啟動超時的情況下引發(fā),一般這個超時時間設(shè)為 10s,如果 10s 之內(nèi)一個 Activity 依然沒有成功啟動,那么將發(fā)送異步消息 IDLE_TIMEOUT_MSG 進行資源回收。activityIdleInternal() 的主要任務(wù)是改變系統(tǒng)中 Activity 的狀態(tài)信息,并將其添加到不同狀態(tài)列表中。它的主要工如下:

  首先,調(diào)用 scheduleAppGcsLocked() 方法通知所有進行中的任務(wù)進行垃圾回收。scheduleAppGcsLocked() 將進行調(diào)度 JVM 的 garbage collect,回收一部分內(nèi)存空間,這里僅僅是通知每個進程自行進程垃圾檢查并調(diào)度回收時間,而非同步回收。

  然后,取出 mStoppingActivities 和 mFinishigActivities 列表中的所有內(nèi)容,暫存在臨時變量中。這兩個列表分別存儲了當(dāng)前狀態(tài)為 stop 和 finishi 的 activity 對象。對于 stop 列表,如果其中的 activity 的 finish 狀態(tài)為 true,判斷是不是要立即停止,如果要立即停止則調(diào)用 destroyActivityLocked() 通知目標(biāo)進程調(diào)用 onDestroy() 方法,否則,先調(diào)用resumeTopActivity() 運行下一個 Activity。如果 finish 狀態(tài)為 false,則調(diào)用 stopActivityLocked() 通知客戶進程停止該 Activity,這種情況一般發(fā)生在調(diào)用 startActivity() 后。對于 finish 列表,直接調(diào)用 destroyActivityLocked() 通知客戶進程銷毀目標(biāo) Activity。這里的 destroyActivityLocked 等函數(shù)并沒有真正意義上改變內(nèi)存的使用,只是將其狀態(tài)改變?yōu)椤霸试S回收”,真正的回收在下面即將調(diào)用的 trimApplications() 函數(shù)中。

  private final void trimApplications() {synchronized (this) {// First remove any unused application processes whose package// has been removed.for (i=mRemovedProcesses.size()-1; i>=0; i--) {(1)//kill process;}if (!updateOomAdjLocked()) {(2)//do something default}// Finally, if there are too many activities now running, try to// finish as many as we can to get back down to the limit.(3)do something}}

 。1)當(dāng)程序執(zhí)行到 trimApplications() 之后,首先檢查 mRemovedProcesses 列表中的進程。mRemovedProcesses 列表中主要包含了 crash 的進程、5 秒內(nèi)沒有響應(yīng)并被用戶選在強制關(guān)閉的進程、以及應(yīng)用開發(fā)這調(diào)用 killBackgroundProcess 想要殺死的進程。調(diào)用 Process.killProcess 將所有此類進程全部殺死。

 。2)調(diào)用 updateOomAdjLocked() 函數(shù),若成功返回,說明 Linux 內(nèi)核支持 setOomAdj() 接口,updateOomAdjLocked 將修改 adj 的值并通知 linux 內(nèi)核,內(nèi)核根據(jù) adj 值以及內(nèi)存使用情況動態(tài)管理進程資源(lowmemorykiller 和 oom_killer)。若 updateOomAdjLocked() 返回為假,則表示當(dāng)前系統(tǒng)不支持 setOomAdj() 接口,將在本地進行默認(rèn)的資源回收。

  (3)最后,如果當(dāng)前依然運行了過多的 Activity,對多余的 Activity 進行回收。 trimApplications() 的大多數(shù)的代碼都在處理 Oom_killer 不存在情況下的默認(rèn)資源回收,下面對其默認(rèn)回收過程(即代碼中標(biāo)記(2)的位置)進行進一步分析。其回收過程可大致描述如下。

  步驟一,獲取當(dāng)前所有運行的進程 mLruProcesses,mLruProcesses 中的排序規(guī)則是按最近使用時間。對 mLruProcesses 中不能被關(guān)閉的進程進行計數(shù),這些不能被關(guān)閉的進程包括運行 service 的進程,運行broadcast receiver 的進程等。

  步驟二, 設(shè)當(dāng)前最大運行進程數(shù) curMaxProcs = curMaxProcs + numServiceProcs(即默認(rèn)最大進程數(shù)與運行 Service 的進程數(shù)之和),如果當(dāng)前進程的數(shù)量 mRemovedProcesses.size() 大于這個值,則遍歷所有當(dāng)前運行的進程,殺死符合條件的那些進程并釋放內(nèi)存。進程被殺死的條件是:必須是非 persistent 進程,即非系統(tǒng)進程,必須是空進程,即進程中沒有任何 activity 存在。如果殺死存在 Activity 的進程,有可能關(guān)閉用戶正在使用的程序,或者使應(yīng)用程序恢復(fù)的時延變大,從而影響用戶體驗;必須無 broadcast receiver。運行 broadcast receiver 一般都在等待一個事件的發(fā)生,用戶并不希望此類程序被系統(tǒng)強制關(guān)閉;進程中 service 的數(shù)量必須為 0。存在 service 的進程很有可能在為一個或者多個程序提供某種服務(wù),如 GPS 定位服務(wù)。殺死此類進程將使其他進程無法正常服務(wù)。

  步驟三,再次檢查當(dāng)前運行的進程,如果 mRemovedProcesses.size() 仍然大于 curMaxProcs,則放寬條件再次進行回收。

  步驟四,上面 3 個過程都是針對整個 process 進行的資源回收。在以上過程執(zhí)行完畢之后,將在更小的粒度上對 Activity 的資源進行回收。與上面所述類似,列表 mLRUActivities 存儲了當(dāng)前所有運行中的 Activity,排序規(guī)則同樣為最少訪問原則。mLRUActivities.size() 返回系統(tǒng)中運行的 Activity 的數(shù)量,當(dāng)其大于 MAX_ACTIVITIES(MAX_ACTIVITIES 是一個常量,一般值為 20,代表系統(tǒng)中最大允許同時存在的 Activity)時。將回收部分滿足條件的 Activity 以減少內(nèi)存的使用。 這里回收的只是 Activity 的內(nèi)存資源,并不會殺死進程,也不會影響進程的運行。當(dāng)進程需要調(diào)用被殺掉的 Activity 時,可以從保存的狀態(tài)中回復(fù),當(dāng)然可能需要相對長一點的時延。

  Linux 內(nèi)核中的內(nèi)存回收

  lowmemorykiller

  trimApplications() 函數(shù)中會執(zhí)行一個叫做 updateOomAdjLocked() 的函數(shù),如果返回 false,則執(zhí)行默認(rèn)回收,若返回 true 則不執(zhí)行默認(rèn)內(nèi)存回收。

  updateOomAdjLocked 將針對每一個進程更新一個名為 adj 的變量,并將其告知 Linux 內(nèi)核,內(nèi)核維護一個包含 adj 的數(shù)據(jù)結(jié)構(gòu)(即進程表),并通過 lowmemorykiller 檢查系統(tǒng)內(nèi)存的使用情況,在內(nèi)存不足的情況下殺死一些進程并釋放內(nèi)存。

  由于 Android 操作系統(tǒng)中的所有應(yīng)用程序都運行在獨立的 Dalvik 虛擬機環(huán)境中,Linux 內(nèi)核無法獲知每個進程的運行狀態(tài),也就無法為每個進程維護一個合適的 adj 值,因此,Android Application Framework 中必須提供一套機制以動態(tài)的更新每個進程的 adj。這就是 updateOomAdjLocked()。

  Android 基于進程中運行的組件及其狀態(tài)規(guī)定了默認(rèn)的五個回收優(yōu)先級:

  IMPORTANCE_FOREGROUND:

  IMPORTANCE_VISIBLE:

  IMPORTANCE_SERVICE:

  IMPORTANCE_BACKGROUND:

  IMPORTANCE_EMPTY:

【Android操作系統(tǒng)的內(nèi)存回收的策略是什么】相關(guān)文章:

Java內(nèi)存回收07-17

Java內(nèi)存回收相關(guān)知識10-09

關(guān)于android操作系統(tǒng)05-30

Android操作系統(tǒng)的發(fā)展與未來08-19

android操作系統(tǒng)的設(shè)置過程09-13

Android操作系統(tǒng)的安全機制09-13

操作系統(tǒng)內(nèi)存優(yōu)化的攻略總結(jié)10-31

教你如何檢查inux操作系統(tǒng)的內(nèi)存07-31

Windows XP操作系統(tǒng)內(nèi)存性能優(yōu)化10-08