Android如何應(yīng)對內(nèi)存回收機制

前言

前段時間曾做過一個定制車載OS(基于Linux、Android)的項目,該操作系統(tǒng)的內(nèi)存不足、內(nèi)存管理欠佳,并且在定制Linux內(nèi)核時給Payment、Music等應(yīng)用分配了較高的進程優(yōu)先級,導(dǎo)致其余應(yīng)用總是出現(xiàn)內(nèi)存被系統(tǒng)回收的情況,時常出現(xiàn)一些匪夷所思的BUG。

Android系統(tǒng)中的進程管理

進程優(yōu)先級的設(shè)置

對于每一個運行中的進程,Linux內(nèi)核都通過proc文件系統(tǒng)暴露這樣一個文件來允許其他程序修改指定進程的優(yōu)先級:/proc/[pid]/oom_score_adj。(修改這個文件需要root權(quán)限)
這個文件允許的值的范圍是:-1000 ~ +1000之間。值越小,表示進程越重要。

當(dāng)內(nèi)存非常緊張時,系統(tǒng)便會遍歷所有進程,以確定哪個進程需要被殺死以回收內(nèi)存,此時便會讀取oom_score_adj 這個文件的值。

進程優(yōu)先級的影響范圍

在Android系統(tǒng)中,進程的優(yōu)先級影響著以下三個因素:

  • 當(dāng)內(nèi)存緊張時,系統(tǒng)對于進程的回收策略
  • 系統(tǒng)對于進程的CPU調(diào)度策略
  • 虛擬機對于進程的內(nèi)存分配和垃圾回收策略

如何提高進程優(yōu)先級

  1. AndroidManifest.xml中的Application節(jié)點內(nèi)添加android:persistent="true";
  2. 重載back按鍵事件,讓activity在后臺運行,不要Destroy;
  3. 啟動Service,并設(shè)置前臺運行方式;
  4. 與NotificationManager交互,讓進程變成可感知進程;
  5. 發(fā)送/接收廣播,進行進程?;?。

如何在Activity被銷毀時進行數(shù)據(jù)緩存

當(dāng)進程不可避免的被銷毀時,可以考慮對頁面當(dāng)前數(shù)據(jù)、部分控件狀態(tài)進行緩存,這樣可以避免部分bug、優(yōu)化用戶體驗。

Activity重建時,系統(tǒng)會在銷毀前調(diào)用onSaveInstanceState方法(調(diào)用時序在onStop之前),在重建時調(diào)用onRestoreInstanceState方法恢復(fù)緩存數(shù)據(jù)。我們可以重寫onRestoreInstanceState方法恢復(fù)數(shù)據(jù),也可以在onCreate中使用savedInstanceState來恢復(fù)數(shù)據(jù)(需要對savedInstanceState判空)。

實例如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);
    Log.d(TAG, "onCreate: ");

    //恢復(fù)數(shù)據(jù)位置1(需要對savedInstanceState判空)
    if (null != savedInstanceState) {
        String string = savedInstanceState.getString("cache");
        Log.d(TAG, "onCreate: " + string);
    }
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    //恢復(fù)數(shù)據(jù)位置2(官方推薦)
    String string = savedInstanceState.getString("cache");
    Log.d(TAG, "onRestoreInstanceState: " + string);
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString("cache", "Cicada");
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 2.1 Activity 2.1.1 Activity的生命周期全面分析 典型情況下的生命周期:在用戶參與的情況下...
    AndroidMaster閱讀 3,272評論 0 8
  • 為了面試,為了高工資,廢話不多說,不定期更新。 1. Activity正常和異常情況下的生命周期分析。 Activ...
    24K男閱讀 881評論 0 0
  • 別人的總結(jié)不一定適合自己,所以盡量多做一些自己的總結(jié),針對自己的薄弱點重點說明,適當(dāng)?shù)慕梃b別人,少走一些彎路。最重...
    renkuo閱讀 7,594評論 2 48
  • 整理一些常見的Android面試題(針對于2~3年開發(fā)經(jīng)驗中所遇到的問題) synchronized鎖靜態(tài)方法和非...
    appzy閱讀 2,448評論 4 18
  • 大部分引自:https://github.com/francistao/LearningNotes/blob/ma...
    zhangweiheb閱讀 197評論 0 0

友情鏈接更多精彩內(nèi)容