进程终止分析之二

    xiaoxiao2021-03-25  72

    1, 概述

    在系统内存较低时就会杀死一些进程,最明显的在卸载一个apk之前会杀死该apk所在的进程。在PMS的deletePackageLI方法中会调用killApplication方法杀死进程。因此,本文以killApplication方法为例来论述杀死进程的过程。当然在android系统中,还有很多情况下会杀死进程,例如在很多异常的时候会直接杀死进程。Java层基本都是在AMS中通过Process的方法杀死进程的。

     

    2, kill进程

    ProcessRecord的kill方法如下,

    void kill(String reason, boolean noisy) { if (!killedByAm) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill"); if (noisy) { Slog.i(TAG, "Killing " + toShortString() + " (adj " + setAdj + "): " + reason); } EventLog.writeEvent(EventLogTags.AM_KILL, userId, pid, processName, setAdj, reason); Process.killProcessQuiet(pid); Process.killProcessGroup(uid, pid); if (!persistent) { killed = true; killedByAm = true; } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } }

    直接调用Process的静态方法killProcessQuiet/ killProcessGroup

    其实,在Process中,还有一个killProcess方法也可以杀死进程。

     

    killProcess方法如下,

    public static final void killProcess(int pid) { sendSignal(pid, SIGNAL_KILL); } public static final native void sendSignal(int pid, int signal);

    Java层的sendSignal方法对应着android_util_Process.cpp的android_os_Process_sendSignal方法

    android_os_Process_sendSignal方法如下,

    void android_os_Process_sendSignal(JNIEnv* env, jobject clazz, jint pid, jint sig) { if (pid > 0) { ALOGI("Sending signal. PID: %" PRId32 " SIG: %" PRId32, pid, sig); kill(pid, sig); } }

    ProcessRecord的kill调用流程图如下,

    android_util_Process.cpp的android_os_Process_sendSignalQuiet方法如下,

    void android_os_Process_sendSignalQuiet(JNIEnv* env, jobject clazz, jint pid, jint sig) { if (pid > 0) { kill(pid, sig); } }

    由此可见, killProcess和killProcessQuiet方法都是通过JNI机制最后调用kill方法来实现的。

     

    再来看killProcessGroup方法是如何调用的。

    android_os_Process_killProcessGroup方法如下,

    jint android_os_Process_killProcessGroup(JNIEnv* env, jobject clazz, jint uid, jint pid) { return killProcessGroup(uid, pid, SIGKILL); }

    processgroup.cpp中的killProcessGroup方法如下,

    static int killProcessGroupOnce(uid_t uid, int initialPid, int signal) { int processes = 0; struct ctx ctx; pid_t pid; ctx.initialized = false; // 获取进程,逐个杀死 while ((pid = getOneAppProcess(uid, initialPid, &ctx)) >= 0) { processes++; if (pid == 0) { // Should never happen... but if it does, trying to kill this // will boomerang right back and kill us! Let's not let that happen. SLOGW("Yikes, we've been told to kill pid 0! How about we don't do that."); continue; } if (pid != initialPid) { // We want to be noisy about killing processes so we can understand // what is going on in the log; however, don't be noisy about the base // process, since that it something we always kill, and we have already // logged elsewhere about killing it. SLOGI("Killing pid %d in uid %d as part of process group %d", pid, uid, initialPid); } int ret = kill(pid, signal); // 杀死进程 if (ret == -1) { SLOGW("failed to kill pid %d: %s", pid, strerror(errno)); } } if (ctx.initialized) { close(ctx.fd); } return processes; }

    所以,process的三个杀死进程的方法都是调用kill方法完成,该方法位于用户空间的Native层。

    更为详细的细节在此就不论述了。

    转载请注明原文地址: https://ju.6miu.com/read-36648.html

    最新回复(0)