Android Lost RAM的統計方法

最近遇到一個Lost RAM佔用內存達到1,296,701K,Free RAM只有157,924K 出現lowmom問題:

  MemInfo:    43,292K slab,   114,292K shmem,    65,292K vm alloc,    12,324K page tables     5,568K kernel stack
               1,572K buffers,   269,472K cached,   188,532K mapped,    75,412K free
  ZRAM:         4K RAM,   520,908K swap total,   520,908K swap free
  Free RAM:   157,924K
  Used RAM:   591,439K
  Lost RAM: 1,296,701K

可以看到,出現lowmom問題是,Used RAM並不高,和正常的相差無幾。

發現問題出現時,Lost RAM異常的大,在總RAM一定的情況下,Used RAM穩定的情況下,Free RAM和Lost RAM 存在此消彼長的現象。

所以這裏我將Lost RAM 統計相關的源碼進行分析。

Lost RAM 統計的源碼:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
        - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
        - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();

我們可以使用命令:adb shell "dumpsys meminfo |grep RAM "

查看正常設備設備RAM信息。

Total RAM: 2,049,328K (status moderate)
 Free RAM: 1,267,152K (   37,644K cached pss +   345,436K cached kernel +   884,072K free)
 Used RAM:   487,842K (  307,414K used pss +   180,428K kernel)
 Lost RAM:   294,330K
     ZRAM:         4K physical used for         0K in swap (  520,908K total swap)
   Tuning: 192 (large 512), oom   184,320K, restore limit    61,440K (high-end-gfx)

即:Lost RAM =2,049,328K-((37,644K+307,414K)-totalSwapPss)- 884,072K-345,436K-180,428K-4k =294,330K

也就是Lost RAM 統計信息中,除了totalSwapPss未在上述命令查詢結果中直接顯示外,其他信息直接可以使用命令查看到。

可以看到正常情況下:2049328-(37644+307414)-884072-345436-180428-4-294330= -totalSwapPss = 0.

可以看到,正常情況下totalSwapPss的值並不大。

繼續看源碼:

    final void dumpApplicationMemoryUsage(FileDescriptor fd,
            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
        ...

        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
        ...
        long totalSwapPss = 0;
        ...
        Debug.MemoryInfo mi = null;
        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
                ...
                final long myTotalSwapPss = mi.getTotalSwappedOutPss();

                synchronized (this) {
                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
                        // Record this for posterity if the process has been stable.
                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
                    }
                }

                if (!isCheckinRequest && mi != null) {
                    ...
                    totalSwapPss += myTotalSwapPss;// 所有進程swap佔用空間總和
                    ...
                }
            }
        }
        ...
    }

totalSwapPss 是所有進程swap佔用空間總和。再其他值都正常的情況下,Lost RAM和totalSwapPss成正比關係。

所以接下來,需要進一步取排查totalSwapPss究竟和哪個進程有關係?

排查思路:將totalSwapPss += myTotalSwapPss;// 所有進程swap佔用空間總和 這一行前面打印進程號。

排查結果:totalSwapPss實際上爲0,日誌打印各進程的myTotalSwapPss,所以這個思路無法定位問題。所以有了下一篇:Lost RAM可能的原因

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章