最近遇到一個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可能的原因