Android Write a process/service that will never be killed

Source: Internet
Author: User
Tags split

  Android system has its own set of methods for memory management, in order to ensure the orderly and stable system of transport letters, the system will automatically allocate, control program memory use. When the system feels the current resources are very limited, in order to ensure that some high priority programs can run, it will kill some of the programs or services he does not think important to free memory. This ensures that programs that are really useful to users are still running. If your Service meets this situation, you'll probably get killed first. But if you increase the service priority so that he can stay a little while, we can use Setforeground (true) to set the service priority.

  Why is foreground? The service that is started by default is marked as background, and the currently running activity is typically marked as foreground, which means that you set up a foreground for the service so that he has the same priority as the running activity. A certain improvement. When this doesn't guarantee that your Service will never be killed, it just increases his priority.   There is a way to give you a clearer presentation, into the $SDK/tools Run command   copy code # ADB shell Dumpsys activity|grep oom_adj        Running Norm Proc # 6:oom_adj=  0 processrecord{43635cf0 12689:com.roiding.netraffic/10028}    Running No RM Proc # 5:oom_adj=  7 processrecord{436feda0 12729:com.android.browser/10006}    Running Norm Proc # 4: oom_adj=  8 processrecord{4367e838 12761:android.process.acore/10016}    Running Norm Proc # 3:oom_adj= & Nbsp;8 processrecord{43691cd8 12754:com.google.process.gapps/10000}    Running PERS Proc # 1:oom_adj=-12 processrecord{43506750 5941:com.android.phone/1001}    Running PERS Proc # 0:oom_adj=-100 processrecord{ 4348fde0 5908:system/1000} Copy a lot of things returned by the code, observe the value of Oom_adj, if it is greater than 81, it belongs to the Backgroud can be killed at any time, the valueThe smaller the certificate the higher the priority, the later the time of the kill. You see the phone's program is-12 to explain the telephone is the phone, everything else is done, also can answer the phone, right. There is also a-100, more knew because it is system and if he is finished, you have to hang up the system.   I am the king of the Tiger's split line                             &NBSP ;      Starting with Android 1.5, a started service can invoke startforeground (int, Notification) to place the service in foreground state, Call Stopforeground (Boolean) to place the service in the background state.   We will call Startforeground (int, Notification) to pass in the parameter Notification, which will display the foreground service in progress in the status bar. The background service is not displayed in the status bar.     in Android 1.0, place a service in the foreground state:   Setforeground (True);  mnm.notify (ID, notification); Place a service in the background state:   Mnm.cancel (ID);  Setforeground (false); By contrast, calling Setforeground (Boolean) in the 1.0 API simply changes the state of the service, and the user is not aware of it. The new API enforces notification and changes to the service state, and the foreground service is displayed in the status bar, and the background service does not.   I am the king of the Tiger's split line                             &NBSP ;  &nbSp   by adding the android:persistent= "true" attribute to the application tag in androidmanifest.xml, it does make sure that the application's process is not killed by LMK. However, the premise is that the application must be a system application, which means that the application does not use the usual installation method. The application's APK package must be placed directly under the/system/app directory. And the system must be restarted before it can take effect.   In addition to a number of general priorities, there are coreserver,system such as the LMK will never be recycled priority. The telephone application in the system is coreserver priority.   By viewing the source code, it is possible to know that only the application's flag are Flag_system and flag_persistent, they are set to Coreserver priority   if (info.flags& ( applicationinfo.flag_system| applicationinfo.flag_persistent)                 = = (Applicationinfo.flag_ system| Applicationinfo.flag_persistent)) {            app.persistent = true;             App.maxadj = Core_server_adj;        } Flag_system is set when the application apk is placed under/system/app. That is why it appears that only setting android:persistent= "true" will still be killed.   testing found that when the application is placed in the/system/app system does not restart, will still be recognized as a normal process. When the system restarts, it starts the process at the beginning and sets the priority to Coreserver.   Through the Dumpsys activity command can clearly see the difference.   Copy Code Running processes (most recent fiRST):     App  # 3:adj=   2/1 processrecord{30858c20 1877:com.android.email/10014} (started-services )     PERS # 2:adj=-100/0 processrecord{308fb390 1713:system/1000} (fixed)     APP  # 1:adj= &N Bsp 0/0 processrecord{30908198 1794:android.process.acore/10005} (top-activity)     PERS # 0:adj= -12/0 ProcessRec ord{3090d488 1789:xiao.xiong.test/10026} (fixed) copying code and ADJ=-12, this process starts immediately after DDMS manual stop   I am the king of the Tiger's split line                                    method In a service, you can first set it to run in the foreground:   Copy code public void Myservice.oncreate () {        super.oncreate (); &nb Sp       Notification Notification = new Notification (Android. R.drawable.my_service_icon, "My_service_name", System.currenttimemillis ());         Pendingintent p_intent = pendingintent.getactivity (this, 0,                 New Intent (this, mymainactivity.class), 0);         Notification.setlatesteventinfo (this, "myservicenotification," Myservicenotification are running! ", p_intent);         LOG.D (TAG, String.Format ("notification =%s", notification));         Startforeground (0x1982, notification);  //Notification id:0x1982, can name it as you. The application under/system/app is more privileged than the application under/data/app, for example, if you set the Persistent property to true in its manifest.xml file, you can protect it from out-of-memory The effect of killer.   such as application ' Phone ' androidmanifest.xml file:   <application android:name= "Phoneapp"         & nbsp        android:persistent= "true"                  android : label= "@string/dialericonlabel"                  android:icon= "@drawable Ic_launcher_phone ">         &nbsp ...     </applicatiOn> set after the app to upgrade to the system core level, in any case will not be killed, settings->applications inside will also block out the stop operation.   Copy code before setting the log:    Proc #19: adj=svc  /b 4067b028 255:com.xxx.xxx/10001 (started-services) & nbsp   # Cat/proc/255/oom_adj     4 set log:   PERS #19: adj=core/f 406291f0 155:com.xxx.xxx/10001 (fixed )     # Cat/proc/155/oom_adj      -12                # this is Core_server_adj Note: The Oom_adj of the INIT process is-16 (that is, System_adj): Cat  /proc/1/oom_adj Copy Code Android related part analysis in file frameworks/base/ Services/java/com/android/server/am/activitymanagerservice.java has the following code:   Copy Code final Processrecord addapplocked (ApplicationInfo info) {        Processrecord app = getprocessrecordlocked ( Info.processname, Info.uid);           if (app = null) {            app = Newprocessrecordlock Ed (null, info, NULL);             MPROCESSNAMes.put (Info.processname, Info.uid, app);             updatelruprocesslocked (app, True, true);        }               if (info.flags& (applicationinfo.flag_s ystem| applicationinfo.flag_persistent)                 = = (Applicationinfo.flag_ system| Applicationinfo.flag_persistent)) {            app.persistent = true;             App.maxadj = Core_server_adj;            //This constant value is-12.        }             if (App.thread = null && mpersistentstart Ingprocesses.indexof (APP) < 0) {            Mpersistentstartingprocesses.add (APP) &nbs P           startprocesslocked (app, "added application", app.processname);        }       &nbsp       return app;     Copy code visible to be a CORE service (i.e. App.maxadj = Core_server_adj (-12)), the application requires Flag_system and flag_persistent two flags, Flag_system refers to the application is located under/system/app, flag_persistent refers to the persistent attribute.   for frameworks/base/services/java/com/android/server/ Systemserver.java, then call Activitymanagerservice.setsystemprocess ();   set its own App.maxadj into System_adj, that is, 16.   I am the king of the Tiger's split line                             &NBSP ; The processes in      Android are hosted, and processes are automatically recycled when the system is in a tight space. This brings three problems:   Recycling rules:   When to recycle and recycle which one? Avoid manslaughter:   How to prevent being recycled? Data recovery and preservation: What if   is recycled? Android divides processes into 6 levels, from high to low in order of precedence:   foreground process (Foreground_app) visual process (VISIBLE_APP) secondary service process (secondary_server) background processes ( Hidden_app Content Supply Node (content_provider) empty process (Empty_app) features:   If a process contains both service and visual activity, then the process should be attributed to the visual process, Rather than the service process. In addition, the level of a process can be improved if other processes depend on it. For example, a service in a process is bound to a component in the B process, and process A will always be considered as important as the B process at least. The phone service in the system is divided into the foreground process rather than the secondaryService process. In Android, the Oom_adj value of a process also represents its priority. The higher the Oom_adj value represents the lower the process priority. The following property settings are available in file/init.rc:   setprop ro. Foreground_app_adj       0     SetProp ro. Visible_app_adj                     1     SetProp ro. Secondary_server_adj   2     SetProp ro. Hidden_app_min_adj           7     SetProp ro. Content_provider_adj  14     SetProp ro. Empty_app_adj                    15/INIT.RC, the Oom_adj of the process (init process) with PID 1 Set to System_adj ( -16):   # SET init its forked children ' s Oom_adj.     write/proc/1/oom_adj–16 View native settings: &nbsp ; Cat/sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15 Recycle, file/init.rc:   setprop ro. Foreground_app_mem       1536      //   6m    setprop ro. Visible_app_mem                   &NBSP 2048    /   8m    setprop ro. Secondary_server_mem   4096    // 16m    setprop ro. Hidden_app_mem                     5120    // 20m &nbsp ;  setprop ro. Content_provider_mem    5632    // 22.4m    setprop ro. Empty_app_mem                      6144    / 24m These numbers are the corresponding memory thresholds, and once they are below that, Android begins to turn off the process in order. Note that the units of these numbers are page:1 page = 4 KB. So the above six digits correspond to (MB): 6,8,16,20,22,24.   View current memory threshold settings:   Cat/sys/module/lowmemorykiller/parameters/minfree to reset the value (corresponding to different requirements):   echo   " 1536,2048,4096,5120,15360,23040 ">/sys/module/lowmemorykiller/parameters/minfree so that when the available memory is less than 90MB, it starts to kill the" empty process ". When the available memory is less than 60MB, the "Content supply node" class process begins to kill.   Specific recycling implementation in Activitymanagerservice.java function Trimapplications ():   Remove the unwanted process that package has been unloaded first; Update Oom_adj value based on current state of the process , and then do the following: 1 Removing the process of no activity in operation; 2 If the AP has saved all activity states, end this AP. Finally, if there are still a lot of activities running, remove the activity that the activity state has saved. Update Oom_adj Value:   Calculates the oom_adj of the process in the computeoomadjlocked () of the Activitymanagerservice.java file, for example:   if (app = Top_app) {           //The last app on the ' list is the ' foreground app.             adj = Foreground_app_adj;             App.adjtype = "top-activity";        } I am the king of the Tiger's split line                       &NB Sp            Android kernel low memory killer   Android's low memory Killer kill on demand (when system memory is scarce) The dead process frees its memory and the source code is in KERNEL/DRIVERS/MISC/LOWMEMORYKILLER.C. Simply put, it is to look for the most appropriate process to kill, thus freeing up the memory it occupies.   The most appropriate process is:   OOM_ADJ the greater the use of physical memory as soon as a process is selected, the kernel sends a sigkill signal to kill it:   copy code for_each_process (p) {    &N Bsp   ...         if (selected = NULL | |   P>oomkilladj > Selected->oomkilladj | |               (P->oomkilladj = Selected->oomkilladj && tasksize > Sel ected_tasksize)         {             selected = p;        }   &NBSP}    if (selected!= NULL) {        Force_sig (SIGKILL, selecte D);   &NBSP to copy Code view LRU list: adb shell Dumpsys activity   when Activitydemo in the foreground:   The process that contains the service has a higher priority, In computeoomadjlocked it is divided into two categories:   copy code static final int max_service_inactivity = 30*60*1000;                        if (now < S.lastactivity+max_servic e_inactivity)) {               if (adj > Secondary_server_adj) {                            adj = Secondary_server_adj;                            App.adjtype = "started-services";                             App.hidden = false;               &nbsp      }       if (Adj > Secondar Y_server_adj) {                        App.adjtype = "Started -bg-services ";      } copying code completely makes it impossible for a process to be killed, and we can make it less likely to kill the process by doing something:   to increase the priority of the process: * Background operation is in the form of service running at the front desk, Because a process running a service is higher than a hierarchy running a background activity; * Pressing the back key causes the activity in the process to run in the background instead of destory, and overload the back key (no activity in the running process is killed first). * Dependent on other high priority processes; Force modify Process properties: * Set in Process: Setpersistent (TRUE); * Set in the manifest file (as above).
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.