平台
RK3288 + Android 7.1
问题
dumpsys meminfo 执行后无法获取APP内存信息
问题LOG:
rk3288:/ $ dumpsys meminfo
Applications Memory Usage (in Kilobytes):
Uptime: 2236645 Realtime: 2236645
Total PSS by process:
70,361K: system (pid 380)
18,544K: com.android.settings (pid 631)
8,734K: android.rockchip.update.service (pid 1184)
6,630K: com.android.keychain (pid 1137)
6,393K: com.hsdz.systemcontroler:shellservice (pid 728)
6,341K: com.hsdz.systemcontroler:sysinfo (pid 745)
5,965K: com.cghs.stresstest (pid 1029)
558K: servicemanager (pid 204)
0K: com.android.providers.calendar (pid 1284)
0K: android.process.media (pid 1200)
0K: com.android.printspooler (pid 1051)
0K: com.android.calendar (pid 1240)
0K: com.android.email (pid 1268)
0K: com.android.onetimeinitializer (pid 1330)
0K: com.android.managedprovisioning (pid 1313)
0K: com.android.deskclock (pid 998)
0K: com.android.launcher3 (pid 1100 / activities)
0K: com.android.inputmethod.pinyin (pid 1013)
0K: com.android.smspush (pid 1084)
0K: android.ext.services (pid 978)
0K: com.android.systemui (pid 608)
0K: com.android.phone (pid 603)
0K: /init (pid 1)
0K: ueventd (pid 162)
0K: logd (pid 182)
0K: debuggerd (pid 189)
0K: vold (pid 190)
0K: debuggerd:signaller (pid 191)
0K: healthd (pid 200)
0K: displayd (pid 201)
0K: tee-supplicant (pid 202)
0K: lmkd (pid 203)
0K: surfaceflinger (pid 205)
0K: sh (pid 214)
0K: rild (pid 215)
0K: adbd (pid 217)
0K: zygote (pid 223)
0K: audioserver (pid 224)
0K: cameraserver (pid 225)
0K: drmserver (pid 226)
0K: installd (pid 227)
0K: keystore (pid 228)
0K: media.codec (pid 229)
0K: mediadrmserver (pid 230)
0K: media.extractor (pid 231)
0K: mediaserver (pid 232)
0K: netd (pid 233)
0K: gatekeeperd (pid 234)
0K: perfprofd (pid 241)
0K: logcat (pid 1369)
0K: sh (pid 1388)
0K: transport (pid 1390)
0K: sh (pid 1409)
0K: dumpsys (pid 1441)
Total PSS by OOM adjustment:
558K: Native
558K: servicemanager (pid 204)
0K: /init (pid 1)
0K: ueventd (pid 162)
0K: logd (pid 182)
0K: debuggerd (pid 189)
0K: vold (pid 190)
0K: debuggerd:signaller (pid 191)
0K: healthd (pid 200)
0K: displayd (pid 201)
0K: tee-supplicant (pid 202)
0K: lmkd (pid 203)
0K: surfaceflinger (pid 205)
0K: sh (pid 214)
0K: rild (pid 215)
0K: adbd (pid 217)
0K: zygote (pid 223)
0K: audioserver (pid 224)
0K: cameraserver (pid 225)
0K: drmserver (pid 226)
0K: installd (pid 227)
0K: keystore (pid 228)
0K: media.codec (pid 229)
0K: mediadrmserver (pid 230)
0K: media.extractor (pid 231)
0K: mediaserver (pid 232)
0K: netd (pid 233)
0K: gatekeeperd (pid 234)
0K: perfprofd (pid 241)
0K: logcat (pid 1369)
0K: sh (pid 1388)
0K: transport (pid 1390)
0K: sh (pid 1409)
0K: dumpsys (pid 1441)
70,361K: System
70,361K: system (pid 380)
5,965K: Persistent
5,965K: com.cghs.stresstest (pid 1029)
0K: com.android.systemui (pid 608)
0K: com.android.phone (pid 603)
15,075K: A Services
8,734K: android.rockchip.update.service (pid 1184)
6,341K: com.hsdz.systemcontroler:sysinfo (pid 745)
6,393K: B Services
6,393K: com.hsdz.systemcontroler:shellservice (pid 728)
25,174K: Cached
18,544K: com.android.settings (pid 631)
6,630K: com.android.keychain (pid 1137)
0K: com.android.providers.calendar (pid 1284)
0K: android.process.media (pid 1200)
0K: com.android.printspooler (pid 1051)
0K: com.android.calendar (pid 1240)
0K: com.android.email (pid 1268)
0K: com.android.onetimeinitializer (pid 1330)
0K: com.android.managedprovisioning (pid 1313)
0K: com.android.deskclock (pid 998)
Total PSS by category:
27,403K: .dex mmap
20,264K: Native
16,707K: .oat mmap
16,285K: Dalvik
11,203K: .apk mmap
10,282K: .art mmap
10,104K: .so mmap
3,947K: Dalvik Other
3,886K: Unknown
1,816K: Other mmap
1,126K: .jar mmap
232K: Stack
106K: .ttf mmap
90K: Ashmem
75K: Other dev
0K: Cursor
0K: Gfx dev
0K: EGL mtrack
0K: GL mtrack
0K: Other mtrack
Total RAM: 2,044,596K (status normal)
Free RAM: 1,405,270K ( 25,174K cached pss + 112,564K cached kernel + 1,267,532K free)
Used RAM: 367,200K ( 98,352K used pss + 268,848K kernel)
Lost RAM: 272,122K
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)
问题LOG 2:获取某个应用内存:
rk3288:/ $ dumpsys meminfo com.android.systemui
Applications Memory Usage (in Kilobytes):
Uptime: 2218086 Realtime: 2218087
** MEMINFO in pid 608 [com.android.systemui] **
Pss Private Private Swap Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 0 0 0 0 13312 10980 2331
Dalvik Heap 0 0 0 0 11424 6855 4569
Unknown 0 0 0 0
TOTAL 0 0 0 0 24736 17835 6900
App Summary
Pss(KB)
------
Java Heap: 0
Native Heap: 0
Code: 0
Stack: 0
Graphics: 0
Private Other: 0
System: 0
TOTAL: 0 TOTAL SWAP (KB): 0
Objects
Views: 538 ViewRootImpl: 4
AppContexts: 9 Activities: 0
Assets: 3 AssetManagers: 5
Local Binders: 118 Proxy Binders: 49
Parcel memory: 9 Parcel count: 39
Death Recipients: 1 OpenSSL Sockets: 0
WebViews: 0
SQL
MEMORY_USED: 0
PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0
正常LOG:
rk3288:/ $ dumpsys meminfo com.android.settings
Applications Memory Usage (in Kilobytes):
Uptime: 2281967 Realtime: 2281967
** MEMINFO in pid 631 [com.android.settings] **
Pss Private Private SwapPss Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 3479 3396 0 0 8192 4758 3433
Dalvik Heap 1629 1580 0 0 3572 2679 893
Dalvik Other 236 236 0 0
Stack 36 36 0 0
Ashmem 4 4 0 0
Other dev 10 0 8 0
.so mmap 2128 124 0 0
.apk mmap 3274 0 96 0
.ttf mmap 106 0 40 0
.dex mmap 2952 4 2948 0
.oat mmap 2204 0 68 0
.art mmap 1400 964 0 0
Other mmap 527 4 0 0
Unknown 559 544 0 0
TOTAL 18544 6892 3160 0 11764 7437 4326
App Summary
Pss(KB)
------
Java Heap: 2544
Native Heap: 3396
Code: 3280
Stack: 36
Graphics: 0
Private Other: 796
System: 8492
TOTAL: 18544 TOTAL SWAP PSS: 0
Objects
Views: 1 ViewRootImpl: 0
AppContexts: 2 Activities: 0
Assets: 2 AssetManagers: 2
Local Binders: 10 Proxy Binders: 13
Parcel memory: 3 Parcel count: 12
Death Recipients: 0 OpenSSL Sockets: 0
WebViews: 0
SQL
MEMORY_USED: 0
PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0
分析
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final void dumpApplicationMemoryUsage(FileDescriptor fd,
PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
boolean dumpDetails = false;
boolean dumpFullDetails = false;
boolean dumpDalvik = false;
boolean dumpSummaryOnly = false;
boolean dumpUnreachable = false;
boolean oomOnly = false;
boolean isCompact = false;
boolean localOnly = false;
boolean packages = false;
boolean isCheckinRequest = false;
boolean dumpSwapPss = false;
//...
if (mi == null) {
mi = new Debug.MemoryInfo();
}
if (dumpDetails || (!brief && !oomOnly)) {
Debug.getMemoryInfo(pid, mi);
hasSwapPss = mi.hasSwappedOutPss;
} else {
mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
mi.dalvikPrivateDirty = (int)tmpLong[0];
}
//...
}
frameworks/base/core/java/android/os/Debug.java
/**
* Retrieves information about this processes memory usages. This information is broken down by
* how much is in use by dalvik, the native heap, and everything else.
*
* <p><b>Note:</b> this method directly retrieves memory information for the give process
* from low-level data available to it. It may not be able to retrieve information about
* some protected allocations, such as graphics. If you want to be sure you can see
* all information about allocations by the process, use instead
* {@link android.app.ActivityManager#getProcessMemoryInfo(int[])}.</p>
*/
public static native void getMemoryInfo(MemoryInfo memoryInfo);
frameworks/base/core/jni/android_os_Debug.cpp
static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
jint pid, jobject object)
{
bool foundSwapPss;
stats_t stats[_NUM_HEAP];
memset(&stats, 0, sizeof(stats));
load_maps(pid, stats, &foundSwapPss);
struct graphics_memory_pss graphics_mem;
if (read_memtrack_memory(pid, &graphics_mem) == 0) {
stats[HEAP_GRAPHICS].pss = graphics_mem.graphics;
stats[HEAP_GRAPHICS].privateDirty = graphics_mem.graphics;
stats[HEAP_GL].pss = graphics_mem.gl;
stats[HEAP_GL].privateDirty = graphics_mem.gl;
stats[HEAP_OTHER_MEMTRACK].pss = graphics_mem.other;
stats[HEAP_OTHER_MEMTRACK].privateDirty = graphics_mem.other;
}
for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) {
stats[HEAP_UNKNOWN].pss += stats[i].pss;
stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss;
stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty;
stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty;
stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean;
stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean;
stats[HEAP_UNKNOWN].swappedOut += stats[i].swappedOut;
stats[HEAP_UNKNOWN].swappedOutPss += stats[i].swappedOutPss;
}
for (int i=0; i<_NUM_CORE_HEAP; i++) {
env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss);
env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss);
env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty);
env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty);
env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean);
env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean);
env->SetIntField(object, stat_fields[i].swappedOut_field, stats[i].swappedOut);
env->SetIntField(object, stat_fields[i].swappedOutPss_field, stats[i].swappedOutPss);
}
env->SetBooleanField(object, hasSwappedOutPss_field, foundSwapPss);
jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field);
jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0);
if (otherArray == NULL) {
return;
}
int j=0;
for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) {
otherArray[j++] = stats[i].pss;
otherArray[j++] = stats[i].swappablePss;
otherArray[j++] = stats[i].privateDirty;
otherArray[j++] = stats[i].sharedDirty;
otherArray[j++] = stats[i].privateClean;
otherArray[j++] = stats[i].sharedClean;
otherArray[j++] = stats[i].swappedOut;
otherArray[j++] = stats[i].swappedOutPss;
}
env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0);
}
static void load_maps(int pid, stats_t* stats, bool* foundSwapPss)
{
char tmp[128];
FILE *fp;
sprintf(tmp, "/proc/%d/smaps", pid);
fp = fopen(tmp, "r");
if (fp == 0)
{
//问题点在这里, 读取smaps文件时出现访问权限问题.
//load_maps open smaps failed:Permission denied
ALOGE("load_maps open smaps failed:%s", strerror(errno));
return;
}
read_mapinfo(fp, stats, foundSwapPss);
fclose(fp);
}
看下权限,
#SELINUX
rk3288:/proc/1 # ps -Z 397
LABEL USER PID PPID VSIZE RSS WCHAN PC NAME
u:r:system_server:s0 system 397 221 1621612 165364 SyS_epoll_ adc7f7a4 S system_server
rk3288:/ $ ls -lZ proc/1176/smaps
-r--r--r-- 1 u0_a19 u0_a19 u:r:platform_app:s0:c512,c768 0 2013-01-18 23:25 proc/1176/smaps
##LINUX
rk3288:/ $ ls -l proc/1176/smaps
-r--r--r-- 1 u0_a19 u0_a19 0 2013-01-18 23:25 proc/1176/smaps
初步判断权限的问题点:
- SELINUX
- 基本文件权限
一般情况下, SELINUX的LOG会出现:
type=1400 audit(1358525621.570:41): avc: denied { read open } for pid=1449 comm="rmlogger" path="/data/media/0" dev="mmcblk1p14" ino=1137 scontext=u:r:rmlogger:s0 tcontext=u:object_r:media_rw_data_file:s0 tclass=dir permissive=1
然而在多次测试后, 并没有出现类似问题的LOG
之后, 开始折腾这两个文件 :
kernel/fs/namei.c
kernel/fs/open.c
加了一堆关于 -EACCES的LOG, 始终定位不到问题…
最后, 终于在GOOGLE上找到:
framework
kernel
补丁打上, 解决
引用
dumpsys meminfo分析
Linux open系统调用流程浅析
open.c源代码阅读
Androiod 安全上下文的临时更改,命令