简单讨论下lmkd 查杀机制

简单画了一个lmkd 查杀示意图(基于Android W)

原生设计:异步发signal + 异步进程内存回收

系统loading 一高,reaper 线程会有不少的Runnable 或被抢占,导致lmkd 发起了kill,但有时候要等个几百ms,reaper 线程才真正被cpu 调度到。

Google 为了能够让reaper 尽快做完,提升了优先级以及限到大核上 system/memory/lmkd/reaper.cpp

还是不能解决loading 高的时候,从唤醒到实际switch 到cpu 上这段Runnable 长的问题

这就可能会出现,在lmkd 发起kill 到最终实际完成这时间内,如果打开应用,上层会错误的复用"注定会被kill"的processrecord。

关联code(基于Android W)

java 复制代码
 @GuardedBy("mService")
    ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
            int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
            boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
            //....
            // We don't have to do anything more if:
        // (1) There is an existing application record; and
        // (2) The caller doesn't think it is dead, OR there is no thread
        //     object attached to it so we know it couldn't have crashed; and
        // (3) There is a pid assigned to it, so it is either starting or
        //     already running.
        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
                + " app=" + app + " knownToBeDead=" + knownToBeDead
                + " thread=" + (app != null ? app.getThread() : null)
                + " pid=" + (app != null ? app.getPid() : -1));
        ProcessRecord predecessor = null;
        if (app != null && app.getPid() > 0) {
            if ((!knownToBeDead && !app.isKilled()) || app.getThread() == null) {
                // We already have the app running, or are waiting for it to
                // come up (we have a pid but not yet its thread), so keep it.
                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
                // If this is a new package in the process, add the package to the list
                app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
                checkSlow(startTime, "startProcess: done, added package to proc");
                return app;
            }

            // An application record is attached to a previous process,
            // clean it up now.
            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
            checkSlow(startTime, "startProcess: bad proc running, killing");
            ProcessList.killProcessGroup(app.uid, app.getPid());
            checkSlow(startTime, "startProcess: done killing old proc");

            if (!app.isKilled()) {
                // Throw a wtf if it's not killed
                Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process");
            } else {
                Slog.w(TAG_PROCESSES, app.toString() + " is attached to a previous process");
            }
            // We are not going to re-use the ProcessRecord, as we haven't dealt with the cleanup
            // routine of it yet, but we'd set it as the predecessor of the new process.
            predecessor = app;
            app = null;
        } 
相关推荐
Android轮子哥5 小时前
月下载 40 万次的框架是怎么练成的
android
三少爷的鞋5 小时前
Kotlin 协程真的是线程框架吗?
android
三雒5 小时前
ART堆内存系列二:从堆中排除大对象
android·性能优化
Android-Flutter5 小时前
kotlin - 平板分屏,左右拖动,2个Activity计算宽度,使用ActivityOptions、Rect(三)
android·kotlin
zfxwasaboy6 小时前
linux Kbuild详解关于fixdep、Q、quiet、escsq
android·linux·ubuntu
Mr YiRan6 小时前
Android模拟简单的网络请求框架Retrofit实现
android·retrofit
zh_xuan11 小时前
Android Looper源码阅读
android
用户02738518402621 小时前
[Android]RecycleView的item用法
android
前行的小黑炭1 天前
Android :为APK注入“脂肪”,论Android垃圾代码在安全加固中的作用
android·kotlin