九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
【轉(zhuǎn)】怎樣使一個Android應(yīng)用不被殺死?(整理)

怎樣使一個Android應(yīng)用不被殺死?(整理)

(2011-12-02 18:50:54)
標(biāo)簽:

it

參考:http://blog.csdn.net/windskier/article/details/6560925
http://blog.csdn.net/zmyde2010/article/details/6756368
http://blog.sina.com.cn/s/blog_514048cb0100wi2j.html

方法
對于放在/system/app下的應(yīng)用,需要在其Manifest.xml文件中設(shè)置persistent屬性,如應(yīng)用程序'Phone'的AndroidManifest.xml文件:
   <application android:name="PhoneApp"
                android:persistent="true"
                android:label="@string/dialerIconLabel"
                android:icon="@drawable/ic_launcher_phone">
        ...
   </application>
設(shè)置后app提升為系統(tǒng)核心級別,任何情況下不會被kill掉,settings->applications里面也會屏蔽掉stop操作。

這樣
設(shè)置前的log: Proc #19: adj=svc  /B 4067b028 255:com.xxx.xxx/10001 (started-services)
   cat /proc/255/oom_adj
    4
設(shè)置后的log: PERS #19: adj=core /F 406291f0 155:com.xxx.xxx/10001 (fixed)
   cat /proc/155/oom_adj
    -12               # 這是CORE_SERVER_ADJ
注:init進(jìn)程的oom_adj為-16(即SYSTEM_ADJ):cat  /proc/1/oom_adj

在文件frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中有以下的代碼:
    finalProcessRecord addAppLocked(ApplicationInfo info) {
       ProcessRecord app = getProcessRecordLocked(info.processName,info.uid);

       if (app == null) {
           app = newProcessRecordLocked(null, info, null);
           mProcessNames.put(info.processName, info.uid, app);
           updateLruProcessLocked(app, true, true);
          

       if((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
               == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)){
           app.persistent =true;
           app.maxAdj =CORE_SERVER_ADJ           // 這個常數(shù)值為-12。
          
       if (app.thread == null &&mPersistentStartingProcesses.indexOf(app) < 0){
           mPersistentStartingProcesses.add(app);
           startProcessLocked(app, "added application",app.processName);
          

       return app;
    }

可見要想成為core service (即app.maxAdj =CORE_SERVER_ADJ(-12)),應(yīng)用程序需要FLAG_SYSTEM和FLAG_PERSISTENT兩個標(biāo)志,F(xiàn)LAG_SYSTEM指的是應(yīng)用位于/system/app下,F(xiàn)LAG_PERSISTENT就是指persistent屬性。

而對于frameworks/base/services/java/com/android/server/SystemServer.java,則調(diào)用
      ActivityManagerService.setSystemProcess();
把自己的 app.maxAdj 設(shè)置成SYSTEM_ADJ,即-16。

原理
Android中的進(jìn)程是托管的,當(dāng)系統(tǒng)進(jìn)程空間緊張的時候,會依照優(yōu)先級自動進(jìn)行進(jìn)程的回收。由此帶來三個問題:
    1)回收規(guī)則:  什么時候回收與回收哪一個?
    2)避免誤殺:  如何阻止被回收?
    3)數(shù)據(jù)恢復(fù)與保存:  被回收了怎么辦?
 
Android將進(jìn)程分為6個等級,它們按優(yōu)先級順序由高到低依次是:
   1.前臺進(jìn)程( FOREGROUND_APP)
   2.可視進(jìn)程(VISIBLE_APP )
   3. 次要服務(wù)進(jìn)程(SECONDARY_SERVER)
   4.后臺進(jìn)程 (HIDDEN_APP)
  5.內(nèi)容供應(yīng)節(jié)點(CONTENT_PROVIDER)
   6.空進(jìn)程(EMPTY_APP)
 
特征:
1.如果一個進(jìn)程里面同時包含service和可視的activity,那么這個進(jìn)程應(yīng)該歸于可視進(jìn)程,而不是service進(jìn)程。
2.另外,如果其他進(jìn)程依賴于它的話,一個進(jìn)程的等級可以提高。例如,一個A進(jìn)程里的service被綁定到B進(jìn)程里的組件上,進(jìn)程A將總被認(rèn)為至少和B進(jìn)程一樣重要。
3.系統(tǒng)中的phone服務(wù)被劃分到前臺進(jìn)程而不是次要服務(wù)進(jìn)程.
 
在android中,進(jìn)程的oom_adj值也就代表了它的優(yōu)先級。oom_adj值越高代表該進(jìn)程優(yōu)先級越低。文件/init.rc中有以下屬性設(shè)置:
    setpropro.FOREGROUND_APP_ADJ     0
    setpropro.VISIBLE_APP_ADJ                    1
    setpropro.SECONDARY_SERVER_ADJ   2
    setpropro.HIDDEN_APP_MIN_ADJ          7
    setpropro.CONTENT_PROVIDER_ADJ  14
    setpropro.EMPTY_APP_ADJ                   15
/init.rc中,將PID為1的進(jìn)程(init進(jìn)程)的oom_adj設(shè)置為SYSTEM_ADJ(-16)。

查看本機(jī)設(shè)置:
cat /sys/module/lowmemorykiller/parameters/adj
0,1,2,7,14,15
 
回收時機(jī):
文件/init.rc中:
   setpropro.FOREGROUND_APP_MEM      1536     //    6M
   setprop ro.VISIBLE_APP_MEM                2048    //    8M
   setpropro.SECONDARY_SERVER_MEM  4096    //  16M
   setpropro.HIDDEN_APP_MEM                    5120    //  20M
   setpropro.CONTENT_PROVIDER_MEM   5632    //  22.4M
   setpropro.EMPTY_APP_MEM                     6144    //  24M
這些數(shù)字也就是對應(yīng)的內(nèi)存閾值,一旦低于該值,Android便開始按順序關(guān)閉相應(yīng)等級的進(jìn)程。
注意這些數(shù)字的單位是page: 1 page = 4 kB。所以上面的六個數(shù)字對應(yīng)的就是(MB):6,8,16,20,22,24。
 
查看現(xiàn)在的內(nèi)存閾值設(shè)置:
cat /sys/module/lowmemorykiller/parameters/minfree

要想重新設(shè)置該值(對應(yīng)不同的需求):
echo  "1536,2048,4096,5120,15360,23040">/sys/module/lowmemorykiller/parameters/minfree
這樣當(dāng)可用內(nèi)存低于90MB的時候便開始?xì)⑺?空進(jìn)程",而當(dāng)可用內(nèi)存低于60MB的時候才開始?xì)⑺?內(nèi)容供應(yīng)節(jié)點"類進(jìn)程。
 
具體的回收實現(xiàn)在ActivityManagerService.java中的函數(shù)trimApplications():
   1.首先移除package已被卸載的無用進(jìn)程;
  2.基于進(jìn)程當(dāng)前狀態(tài),更新oom_adj值,然后進(jìn)行以下操作:
        1) 移除沒有activity在運行的進(jìn)程;
        2) 如果AP已經(jīng)保存了所有的activity狀態(tài),結(jié)束這個AP。
   3. 最后,如果目前還是有很多activities在運行,那么移除那些activity狀態(tài)已經(jīng)保存好的activity。
 

更新oom_adj的值:
在ActivityManagerService.java文件的ComputeOomAdjLocked()中計算出進(jìn)程的oom_adj,例如:
    if (app == TOP_APP) {
           // The last app on the list is the foreground app.
           adj = FOREGROUND_APP_ADJ;
           app.adjType = "top-activity";
       }
 
Android kernel中的low memorykiller
Android的Low MemoryKiller根據(jù)需要(當(dāng)系統(tǒng)內(nèi)存短缺時)殺死進(jìn)程釋放其內(nèi)存,源代碼在kernel/drivers/misc/lowmemorykiller.c中。簡單說,就是尋找一個最合適的進(jìn)程殺死,從而釋放它占用的內(nèi)存。
最合適的進(jìn)程是:
    oom_adj越大
    占用物理內(nèi)存越多
 
一旦一個進(jìn)程被選中,內(nèi)核會發(fā)送SIGKILL信號將之殺死:
   for_each_process(p) {
       ……
       if(selected == NULL ||  p->oomkilladj >selected->oomkilladj ||
            (p->oomkilladj ==selected->oomkilladj&& tasksize >selected_tasksize))
       {
            selected = p;
       }
   }
   if(selected != NULL) {
       force_sig(SIGKILL, selected);
   }
 
查看LRU列表:adb shell dumpsys activity
當(dāng)activitydemo在前臺時: 
包含Service的進(jìn)程的優(yōu)先級比較高,在computeOomAdjLocked中將其分為了兩小類:
     static final int MAX_SERVICE_INACTIVITY =30*60*1000;                 
      if (now< (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
              if (adj > SECONDARY_SERVER_ADJ) {
                           adj = SECONDARY_SERVER_ADJ;
                           app.adjType = "started-services";
                           app.hidden = false;
              }
     }
     if (adj > SECONDARY_SERVER_ADJ) {
                       app.adjType = "started-bg-services";
     }
 

完全讓進(jìn)程不被kill是不可能的,我們可以通過一些操作,使進(jìn)程被kill的幾率變?。?br>  1) 提高進(jìn)程的優(yōu)先級:
       * 后臺操作采用Service形式,因為一個運行著service的進(jìn)程比一個運行著后臺activity的等級高;
       *按back鍵使得進(jìn)程中的activity在后臺運行而不是destory,需重載back按鍵(沒有任何activity在運行的進(jìn)程優(yōu)先被殺).
       * 依賴于其他優(yōu)先級高的進(jìn)程;

  2) 強(qiáng)制修改進(jìn)程屬性:
       * 在進(jìn)程中設(shè)置:setPersistent(true);
       * 在Manifest文件中設(shè)置(如上)。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android下寫一個永遠(yuǎn)不會被KILL掉的進(jìn)程/服務(wù)
Android的進(jìn)程優(yōu)先級與進(jìn)程回收
慎用內(nèi)存釋放軟件,剖析1Gram手機(jī)的內(nèi)存原理
一種提高Android應(yīng)用進(jìn)程存活率新方法 | SkySeraph
Android后臺殺死系列之三:LowMemoryKiller原理(4.3
關(guān)于 Android 進(jìn)程保活,你所需要知道的一切
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服