sssss:/ # dumpsys meminfo com.android.home
Applications Memory Usage (in Kilobytes):
Uptime: 5285433 Realtime: 6628897
** MEMINFO in pid 5049 [com.android.home] **
Pss Private Private SwapPss Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 63416 63204 0 0 113664 77388 36275
Dalvik Heap 4859 4820 0 0 7057 5309 1748
Dalvik Other 3949 3948 0 0
Stack 56 56 0 0
Ashmem 10 8 0 0
Gfx dev 8192 8192 0 0
Other dev 108 0 108 0
.so mmap 3031 288 128 0
.jar mmap 0 0 0 0
.apk mmap 22175 0 19504 0
.ttf mmap 1310 0 256 0
.dex mmap 8945 12 7760 0
.oat mmap 4191 0 192 0
.art mmap 3340 2880 0 0
Other mmap 315 12 176 0
GL mtrack 10444 10444 0 0
Unknown 1282 1276 0 0
TOTAL 135623 95140 28124 0 120721 82697 38023
App Summary
Pss(KB)
------
Java Heap: 7700
Native Heap: 63204
Code: 28140
Stack: 56
Graphics: 18636
Private Other: 5528
System: 12359
TOTAL: 135623 TOTAL SWAP PSS: 0
Objects
Views: 789 ViewRootImpl: 1
AppContexts: 8 Activities: 1
Assets: 13 AssetManagers: 0
Local Binders: 62 Proxy Binders: 40
Parcel memory: 13 Parcel count: 56
Death Recipients: 2 OpenSSL Sockets: 0
WebViews: 0
SQL
MEMORY_USED: 618
PAGECACHE_OVERFLOW: 129 MALLOC_SIZE: 117
DATABASES
pgsz dbsz Lookaside(b) cache Dbname
4 28 37 43/24/4 /data/user_de/0/com.android.home/databases/est_ev
4 36 93 637/327/25 /data/user_de/0/com.android.home/databases/launcher.db
主要关注 Native heap 和 Dalvik heap/Java heap 的数据从哪里拿的。
这个数据,其实都是在 ActivityManagerService.java的 dumpMemInfoTable函数中打印的。
Pss Private Private SwapPss Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 63416 63204 0 0 113664 77388 36275
比如这个数据,其实是在 ActivityManagerService.java的 dumpMemInfoTable函数中如下代码打印的:
printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
"Private", memInfo.hasSwappedOutPss ? "SwapPss" : "Swap",
"Heap", "Heap", "Heap");
printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
"Clean", "Dirty", "Size", "Alloc", "Free");
printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
"------", "------", "------", "------", "------");
printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
memInfo.nativePrivateDirty,
memInfo.nativePrivateClean,
memInfo.hasSwappedOutPss ? memInfo.nativeSwappedOutPss :
memInfo.nativeSwappedOut,
nativeMax, nativeAllocated, nativeFree);
printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
memInfo.dalvikPrivateDirty,
memInfo.dalvikPrivateClean,
memInfo.hasSwappedOutPss ? memInfo.dalvikSwappedOutPss :
memInfo.dalvikSwappedOut,
dalvikMax, dalvikAllocated, dalvikFree);
可以看到 Native Heap的数据都是从 memInfo的如下几个成员拿到的:
Pss Private Private SwapPss Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap nativePss nativePrivateDirty nativePrivateClean nativeSwappedOut nativeMax nativeAllocated nativeFree
Dalvik Heap dalvikPss dalvikPrivateDirty dalvikPrivateClean dalvikSwappedOut dalvikMax dalvikAllocated dalvikFree
最后三个数据(max /allocated/free)的获取:
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
Runtime runtime = Runtime.getRuntime();
runtime.gc(); // Do GC since countInstancesOfClass counts unreachable objects.
long dalvikMax = runtime.totalMemory() / 1024;
long dalvikFree = runtime.freeMemory() / 1024;
long dalvikAllocated = dalvikMax - dalvikFree;
static jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz)
{
struct mallinfo info = mallinfo();
return (jlong) info.usmblks;
}
static jlong android_os_Debug_getNativeHeapAllocatedSize(JNIEnv *env, jobject clazz)
{
struct mallinfo info = mallinfo();
return (jlong) info.uordblks;
}
static jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz)
{
struct mallinfo info = mallinfo();
return (jlong) info.fordblks;
}
这个mallinfo 实际是用的 je_mallinfo:
(gdb) bt
#0 je_mallinfo () at external/jemalloc/src/android_je_mallinfo.c:22
#1 0x000000733cf2359c in android::android_os_Debug_getNativeHeapSize (env=0x0 <_DYNAMIC>, clazz=0x729e37f7c4) at frameworks/base/core/jni/android_os_Debug.cpp:169
#2 0x00000000759d1874 in android.app.backup.FileBackupHelperBase.ctor [DEDUPED] () from out-cepheus/target/product/cepheus/symbols/system/framework/arm64/boot-framework.oat
#3 0x00000000764f0780 in android.app.ActivityThread$ApplicationThread.dumpMemInfo () from out-cepheus/target/product/cepheus/symbols/system/framework/arm64/boot-framework.oat
#4 0x00000000764f2c74 in android.app.ActivityThread$ApplicationThread.dumpMemInfo () from out-cepheus/target/product/cepheus/symbols/system/framework/arm64/boot-framework.oat
我们查看一下 je_mallinfo:
(gdb) call je_mallinfo()
$1 = {
arena = 0,
ordblks = 0,
smblks = 0,
hblks = 0,
hblkhd = 116391936,
usmblks = 116391936,
fsmblks = 0,
uordblks = 79656472,
fordblks = 36735464,
keepcost = 0
}
(gdb) p 116391936/1024
$3 = 113664
(gdb) p 79656472/1024
$4 = 77789
(gdb) p 36735464/1024
$5 = 35874
(gdb) p 116391936-79656472
$6 = 36735464
所以:
long nativeMax = Debug.getNativeHeapSize() / 1024 = 113664 KB;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024 = 77789 KB;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024 = 35874 KB;
这个数据获取的时候,与上面贴的数据, allocated和free有一点区别,可以忽略,因为不是同一次获取的。
dalvik heap size的获取用到了两个函数:
long dalvikMax = runtime.totalMemory() / 1024;
long dalvikFree = runtime.freeMemory() / 1024;
long dalvikAllocated = dalvikMax - dalvikFree;
对应的实现是:
size_t Heap::GetTotalMemory() const {
return std::max(max_allowed_footprint_, GetBytesAllocated());
}
size_t GetBytesAllocated() const {
return num_bytes_allocated_.LoadSequentiallyConsistent();
}
size_t GetFreeMemory() const {
size_t byte_allocated = num_bytes_allocated_.LoadSequentiallyConsistent();
size_t total_memory = GetTotalMemory();
// Make sure we don't get a negative number.
return total_memory - std::min(total_memory, byte_allocated);
}
size_t GetMaxMemory() const {
// There is some race conditions in the allocation code that can cause bytes allocated to
// become larger than growth_limit_ in rare cases.
return std::max(GetBytesAllocated(), growth_limit_);
}
(gdb) p 'art::Runtime'::instance_->heap_->max_allowed_footprint_
$3 = 7226368
(gdb) p 'art::Runtime'::instance_->heap_->num_bytes_allocated_.__a_
$8 = 5436416
(gdb) p 'art::Runtime'::instance_->heap_->growth_limit_
$7 = 536870912
(gdb) p 'art::Runtime'::instance_->heap_->capacity_
$12 = 536870912
(gdb) p 536870912/1024/1024
$14 = 512
这里当前进程的 growth_limit_ 和 heap_size都是 512M
对应的上面三个数据是:
long dalvikMax = runtime.totalMemory() / 1024 = 7057 KB;
long dalvikFree = runtime.freeMemory() / 1024 = 5309 KB;
long dalvikAllocated = dalvikMax - dalvikFree = 1748 KB;
主要解释 Size,Alloc,Free前面的几个数据的获取:
Pss Private Private SwapPss Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 63416 63204 0 0 113664 77388 36275
Dalvik Heap 4859 4820 0 0 7057 5309 1748
获取方式如下:
printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
memInfo.nativePrivateDirty,
memInfo.nativePrivateClean,
memInfo.hasSwappedOutPss ? memInfo.nativeSwappedOutPss :
memInfo.nativeSwappedOut,
nativeMax, nativeAllocated, nativeFree);
printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
memInfo.dalvikPrivateDirty,
memInfo.dalvikPrivateClean,
memInfo.hasSwappedOutPss ? memInfo.dalvikSwappedOutPss :
memInfo.dalvikSwappedOut,
dalvikMax, dalvikAllocated, dalvikFree);
memInfo其实是从如下函数获取:
Debug.getMemoryInfo(pid, mi);
{ "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)V",
(void*) android_os_Debug_getDirtyPagesPid },
对应实现在:android_os_Debug_getDirtyPagesPid
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);
...
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].rss_field, stats[i].rss);
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);
}
...
}
static void load_maps(int pid, stats_t* stats, bool* foundSwapPss)
{
*foundSwapPss = false;
std::string smaps_path = base::StringPrintf("/proc/%d/smaps", pid);
UniqueFile fp = MakeUniqueFile(smaps_path.c_str(), "re");
if (fp == nullptr) return;
read_mapinfo(fp.get(), stats, foundSwapPss);
}
可以看到其实是读取 "/proc/pid/smaps",进行分析统计的。
实现如下:
static void read_mapinfo(FILE *fp, stats_t* stats, bool* foundSwapPss)
{
...
if(fgets(line, sizeof(line), fp) == 0) return;
while (!done) {
...
if (sscanf(line, "%" SCNx64 "-%" SCNx64 " %*s %*x %*x:%*x %*d%n", &start, &end, &name_pos) != 2) {
skip = true;
} else {
while (isspace(line[name_pos])) {
name_pos += 1;
}
name = line + name_pos;
nameLen = strlen(name);
// Trim the end of the line if it is " (deleted)".
const char* deleted_str = " (deleted)";
if (nameLen > (int)strlen(deleted_str) &&
strcmp(name+nameLen-strlen(deleted_str), deleted_str) == 0) {
nameLen -= strlen(deleted_str);
name[nameLen] = '\0';
}
if ((strstr(name, "[heap]") == name)) {
whichHeap = HEAP_NATIVE;
} else if (strncmp(name, "[anon:libc_malloc]", 18) == 0) {
whichHeap = HEAP_NATIVE;
} else if (strncmp(name, "[stack", 6) == 0) {
whichHeap = HEAP_STACK;
} else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) {
whichHeap = HEAP_SO;
is_swappable = true;
} else if (nameLen > 4 && strcmp(name+nameLen-4, ".jar") == 0) {
whichHeap = HEAP_JAR;
is_swappable = true;
} else if (nameLen > 4 && strcmp(name+nameLen-4, ".apk") == 0) {
whichHeap = HEAP_APK;
is_swappable = true;
} else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) {
whichHeap = HEAP_TTF;
is_swappable = true;
} else if ((nameLen > 4 && strstr(name, ".dex") != NULL) ||
(nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) {
whichHeap = HEAP_DEX;
subHeap = HEAP_DEX_APP_DEX;
is_swappable = true;
} else if (nameLen > 5 && strcmp(name+nameLen-5, ".vdex") == 0) {
whichHeap = HEAP_DEX;
// Handle system@framework@boot* and system/framework/boot*
if (strstr(name, "@boot") != NULL || strstr(name, "/boot") != NULL) {
subHeap = HEAP_DEX_BOOT_VDEX;
} else {
subHeap = HEAP_DEX_APP_VDEX;
}
is_swappable = true;
} else if (nameLen > 4 && strcmp(name+nameLen-4, ".oat") == 0) {
whichHeap = HEAP_OAT;
is_swappable = true;
} else if (nameLen > 4 && strcmp(name+nameLen-4, ".art") == 0) {
whichHeap = HEAP_ART;
// Handle system@framework@boot* and system/framework/boot*
if (strstr(name, "@boot") != NULL || strstr(name, "/boot") != NULL) {
subHeap = HEAP_ART_BOOT;
} else {
subHeap = HEAP_ART_APP;
}
is_swappable = true;
} else if (strncmp(name, "/dev/", 5) == 0) {
if (strncmp(name, "/dev/kgsl-3d0", 13) == 0) {
whichHeap = HEAP_GL_DEV;
} else if (strncmp(name, "/dev/ashmem", 11) == 0) {
if (strncmp(name, "/dev/ashmem/dalvik-", 19) == 0) {
whichHeap = HEAP_DALVIK_OTHER;
if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) {
subHeap = HEAP_DALVIK_OTHER_LINEARALLOC;
} else if ((strstr(name, "/dev/ashmem/dalvik-alloc space") == name) ||
(strstr(name, "/dev/ashmem/dalvik-main space") == name)) {
// This is the regular Dalvik heap.
whichHeap = HEAP_DALVIK;
subHeap = HEAP_DALVIK_NORMAL;
} else if (strstr(name, "/dev/ashmem/dalvik-large object space") == name ||
strstr(name, "/dev/ashmem/dalvik-free list large object space")
== name) {
whichHeap = HEAP_DALVIK;
subHeap = HEAP_DALVIK_LARGE;
} else if (strstr(name, "/dev/ashmem/dalvik-non moving space") == name) {
whichHeap = HEAP_DALVIK;
subHeap = HEAP_DALVIK_NON_MOVING;
} else if (strstr(name, "/dev/ashmem/dalvik-zygote space") == name) {
whichHeap = HEAP_DALVIK;
subHeap = HEAP_DALVIK_ZYGOTE;
} else if (strstr(name, "/dev/ashmem/dalvik-indirect ref") == name) {
subHeap = HEAP_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE;
} else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name ||
strstr(name, "/dev/ashmem/dalvik-data-code-cache") == name) {
subHeap = HEAP_DALVIK_OTHER_CODE_CACHE;
} else if (strstr(name, "/dev/ashmem/dalvik-CompilerMetadata") == name) {
subHeap = HEAP_DALVIK_OTHER_COMPILER_METADATA;
} else {
subHeap = HEAP_DALVIK_OTHER_ACCOUNTING; // Default to accounting.
}
} else if (strncmp(name, "/dev/ashmem/CursorWindow", 24) == 0) {
whichHeap = HEAP_CURSOR;
} else if (strncmp(name, "/dev/ashmem/libc malloc", 23) == 0) {
whichHeap = HEAP_NATIVE;
} else {
whichHeap = HEAP_ASHMEM;
}
} else {
whichHeap = HEAP_UNKNOWN_DEV;
}
} else if (strncmp(name, "[anon:", 6) == 0) {
whichHeap = HEAP_UNKNOWN;
} else if (nameLen > 0) {
whichHeap = HEAP_UNKNOWN_MAP;
} else if (start == prevEnd && prevHeap == HEAP_SO) {
// bss section of a shared library.
whichHeap = HEAP_SO;
}
}
...
while (true) {
if (fgets(line, 1024, fp) == 0) {
done = true;
break;
}
if (line[0] == 'S' && sscanf(line, "Size: %d kB", &temp) == 1) {
/* size = temp; */
} else if (line[0] == 'R' && sscanf(line, "Rss: %d kB", &temp) == 1) {
rss = temp;
} else if (line[0] == 'P' && sscanf(line, "Pss: %d kB", &temp) == 1) {
pss = temp;
} else if (line[0] == 'S' && sscanf(line, "Shared_Clean: %d kB", &temp) == 1) {
shared_clean = temp;
} else if (line[0] == 'S' && sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) {
shared_dirty = temp;
} else if (line[0] == 'P' && sscanf(line, "Private_Clean: %d kB", &temp) == 1) {
private_clean = temp;
} else if (line[0] == 'P' && sscanf(line, "Private_Dirty: %d kB", &temp) == 1) {
private_dirty = temp;
} else if (line[0] == 'R' && sscanf(line, "Referenced: %d kB", &temp) == 1) {
/* referenced = temp; */
} else if (line[0] == 'S' && sscanf(line, "Swap: %d kB", &temp) == 1) {
swapped_out = temp;
} else if (line[0] == 'S' && sscanf(line, "SwapPss: %d kB", &temp) == 1) {
*foundSwapPss = true;
swapped_out_pss = temp;
} else if (sscanf(line, "%" SCNx64 "-%" SCNx64 " %*s %*x %*x:%*x %*d", &start, &end) == 2) {
// looks like a new mapping
// example: "10000000-10001000 ---p 10000000 00:00 0"
break;
}
}
...
if (!skip) {
if (is_swappable && (pss > 0)) {
sharing_proportion = 0.0;
if ((shared_clean > 0) || (shared_dirty > 0)) {
sharing_proportion = (pss - private_clean
- private_dirty)/(shared_clean+shared_dirty);
}
swappable_pss = (sharing_proportion*shared_clean) + private_clean;
} else
swappable_pss = 0;
stats[whichHeap].pss += pss;
stats[whichHeap].swappablePss += swappable_pss;
stats[whichHeap].rss += rss;
stats[whichHeap].privateDirty += private_dirty;
stats[whichHeap].sharedDirty += shared_dirty;
stats[whichHeap].privateClean += private_clean;
stats[whichHeap].sharedClean += shared_clean;
stats[whichHeap].swappedOut += swapped_out;
stats[whichHeap].swappedOutPss += swapped_out_pss;
if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER ||
whichHeap == HEAP_DEX || whichHeap == HEAP_ART) {
stats[subHeap].pss += pss;
stats[subHeap].swappablePss += swappable_pss;
stats[subHeap].rss += rss;
stats[subHeap].privateDirty += private_dirty;
stats[subHeap].sharedDirty += shared_dirty;
stats[subHeap].privateClean += private_clean;
stats[subHeap].sharedClean += shared_clean;
stats[subHeap].swappedOut += swapped_out;
stats[subHeap].swappedOutPss += swapped_out_pss;
}
}
}
Dalvik Heap和Native Heap的数据都来自 stats[HEAP_DALVIK] 和 stats[HEAP_NATIVE];
可以看到read_mapinfo中主要是读取 smaps中各个段的不同信息来进行统计;
查看smaps中一个归属于 Dalvik Heap的段的信息:
12c00000-12f40000 rw-p 00000000 00:05 36382 /dev/ashmem/dalvik-main space (region space) (deleted)
Size: 3328 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 2708 kB
//Dalvik Heap的 Pss Total数据就是smaps中所有属于 dalvik 段的 Pss数值的总和,Native heap的类似
Pss: 2708 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 2708 kB
Referenced: 2708 kB
Anonymous: 2708 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
VmFlags: rd wr mr mw me ac
属于Native Heap的内存段的数据类似:
728ac00000-728b000000 rw-p 00000000 00:00 0 [anon:libc_malloc]
Name: [anon:libc_malloc]
Name: [anon:libc_malloc]
Size: 4096 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 1736 kB
Pss: 1736 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 1736 kB
Referenced: 1736 kB
Anonymous: 1736 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
VmFlags: rd wr mr mw me nr
App Summary对数据又做了一些合并处理:
App Summary
Pss(KB)
------
Java Heap: 7700
Native Heap: 63204
Code: 28140
Stack: 56
Graphics: 18636
Private Other: 5528
System: 12359
TOTAL: 135623 TOTAL SWAP PSS: 0
其数据获取方式如下:
pw.println(" App Summary");
printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "Pss(KB)");
printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "------");
printRow(pw, ONE_COUNT_COLUMN,
"Java Heap:", memInfo.getSummaryJavaHeap());
printRow(pw, ONE_COUNT_COLUMN,
"Native Heap:", memInfo.getSummaryNativeHeap());
printRow(pw, ONE_COUNT_COLUMN,
"Code:", memInfo.getSummaryCode());
printRow(pw, ONE_COUNT_COLUMN,
"Stack:", memInfo.getSummaryStack());
printRow(pw, ONE_COUNT_COLUMN,
"Graphics:", memInfo.getSummaryGraphics());
printRow(pw, ONE_COUNT_COLUMN,
"Private Other:", memInfo.getSummaryPrivateOther());
printRow(pw, ONE_COUNT_COLUMN,
"System:", memInfo.getSummarySystem());
pw.println(" ");
if (memInfo.hasSwappedOutPss) {
printRow(pw, TWO_COUNT_COLUMNS,
"TOTAL:", memInfo.getSummaryTotalPss(),
"TOTAL SWAP PSS:", memInfo.getSummaryTotalSwapPss());
} else {
printRow(pw, TWO_COUNT_COLUMNS,
"TOTAL:", memInfo.getSummaryTotalPss(),
"TOTAL SWAP (KB):", memInfo.getSummaryTotalSwap());
}
这里根据每个数据的获取看一下他们的涵义:
public int getSummaryJavaHeap() {
return dalvikPrivateDirty + getOtherPrivate(OTHER_ART);
}
public int getSummaryNativeHeap() {
return nativePrivateDirty;
}
public int getSummaryCode() {
return getOtherPrivate(OTHER_SO)
+ getOtherPrivate(OTHER_JAR)
+ getOtherPrivate(OTHER_APK)
+ getOtherPrivate(OTHER_TTF)
+ getOtherPrivate(OTHER_DEX)
+ getOtherPrivate(OTHER_OAT);
}
public int getSummaryStack() {
return getOtherPrivateDirty(OTHER_STACK);
}
public int getSummaryGraphics() {
return getOtherPrivate(OTHER_GL_DEV)
+ getOtherPrivate(OTHER_GRAPHICS)
+ getOtherPrivate(OTHER_GL);
}
public int getSummaryPrivateOther() {
return getTotalPrivateClean()
+ getTotalPrivateDirty()
- getSummaryJavaHeap()
- getSummaryNativeHeap()
- getSummaryCode()
- getSummaryStack()
- getSummaryGraphics();
}
public int getSummarySystem() {
return getTotalPss()
- getTotalPrivateClean()
- getTotalPrivateDirty();
}
public int getSummaryTotalPss() {
return getTotalPss();
}
这些 OTHER_ART,OTHER_SO,OTHER_JAR等类型内存的分类参考前面 read_mapinfo的分类即可。
其余 dumpsys meminfo 的实现待调研。