Android APP memory用量如何回收
1. Android APP memory用量都有哪些
部分App的同学不太清楚自己的用量都用在那里,如何快速回收等,这里主要是讲一下用量分布,和快速回收部分内存的方法
$ adb shell dumpsys -t 100 meminfo com.android.systemui
Applications Memory Usage (in Kilobytes):
Uptime: 7193430 Realtime: 70018589
** MEMINFO in pid 5312 [com.android.systemui] **
Pss Private Private SwapPss Rss Heap Heap Heap
Total Dirty Clean Dirty Total Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------
Native Heap 47639 47596 0 16153 49500 74520 68733 5786
Dalvik Heap 12002 10392 0 268 16628 19698 9849 9849
Dalvik Other 1894 1764 0 331 3284
Stack 1472 1472 0 680 1488
Ashmem 70 52 0 0 664
Other dev 77 4 72 0 536
.so mmap 6635 368 756 357 64032
.jar mmap 2578 0 0 0 34024
.apk mmap 17791 0 15032 0 26404
.ttf mmap 258 0 0 0 820
.dex mmap 19236 36 19172 12 19904
.oat mmap 766 0 8 0 16124
.art mmap 12938 12176 84 927 28088
Other mmap 113 8 68 0 968
EGL mtrack 3576 3576 0 0 3576
GL mtrack 33972 33972 0 0 33972
Unknown 982 976 0 182 1324
TOTAL 180909 112392 35192 18910 301336 94218 78582 15635
可以看到主要有
1、Native Heap: 主要是libc_malloc分配的内存
2、Dalvik:这个是虚拟机用量的内存
3、mmap:这个是载入java进程的文件
4、EGL/GL mtrack:这个是显示相关的一些用量
2. Native Heap的用量分析
在性能问题分析方法[1] --- RAM
有讲到,这里讲一下之前没有提到的
1、libc.debug.malloc.program抓取
之前用的方法是发送kill -45和kill -47的信号量
1. $adb root
2. $adb shell setenforce 0
//同时此处加上将/data/local/tmp的权限改成777
adb shell
cd /data/local/
chmod 777 tmp
//32bit使用app_process
3. $setprop libc.debug.malloc.program app_process64
//(如果这个设置不成功,可以adb shell, 进去设置)
4. $setprop libc.debug.malloc.options "backtrace_enable_on_signal backtrace leak_track"
5. $stop
6. $start
//此处指令是可以开始监控了native用量了
7. $kill -45 $(pidof com.android.systemui)
8. 此时你可以去复现问题
//如果问题复现,可以输入这个指令,将在/data/local/tmp目录生成类似改进程堆栈信息的文件
9. $kill -47 $(pidof com.android.systemui)
//(native_heapdump_viewer是在development/scripts里面,这个操作需要复现问题手机的symbols)
10. python development/scripts/native_heapdump_viewer.py --verbose --html backtrace_heap.2225.txt --symbols ***/out/target/product/***/symbols > backtrace_heap.html
现在我们可以使用更简单的方法am dumpheap -n
,其实际是在ActivityThread
中调用Debug.dumpNativeHeap
1. $adb root
2. $adb shell setenforce 0
//同时此处加上将/data/local/tmp的权限改成777
adb shell
cd /data/local/
chmod 777 tmp
//32bit使用app_process
3. $setprop libc.debug.malloc.program app_process64
//(如果卡顿backtrace可以适当改小)
4. $adb shell setprop libc.debug.malloc.options backtrace=64
5. $stop
6. $start
7. 此时你可以去复现问题
//如果问题复现,可以输入这个指令,将在/data/local/tmp目录生成类似改进程堆栈信息的文件
8. $am dumpheap -n $(pidof com.android.systemui) /data/local/tmp/native_heap2.txt
//(native_heapdump_viewer是在development/scripts里面,这个操作需要复现问题手机的symbols)
11. python development/scripts/native_heapdump_viewer.py --verbose --html backtrace_heap.2225.txt --symbols ***/out/target/product/***/symbols > backtrace_heap.html
2、使用Android Studio profile
的Native Size + reference也可以找到一部分native heap的内容(下图gms core的hprof文件用Android Studio打开,此处紧急说明Native Size
、reference
分别在哪个位置)
3. Dalvik Heap的用量分析
这个也可以参考性能问题分析方法[1] --- RAM
,
此处注意一下建议使用Android Studio的profile和MemoryAnalyzer
2个工具结合分析,分析出来的综合对比
4. mmap的用量分析
这个使用adb shell showmap +pid
形式加上xlsx
的排序,大概你就知道是什么载入app导致用量高了(如果你想要更细的,可以使用adb shell cat /proc/(+pid)/smaps
查看)
5.EGL/GL mtrack的用量分析
ion可以看一部分,但不全
// mtk的自己做的节点
adb shell cat /sys/kernel/debug/ion/ion_mm_heap
//android R/S用这个
adb shell cat /proc/ion/heaps/ion_mm_heap
// 高通的
adb shell cat /sys/kernel/debug/ion/heaps/system
adb shell cat /sys/kernel/debug/dma_buf/dmaprocs // kernel 4.14以后的版本使用这个
主要指的是这部分用量
EGL mtrack 3576 3576 0 0 3576
GL mtrack 33972 33972 0 0 33972
6. Memory用量如何及时回收
我们除了关注索引关系,还需要关注如何尽快释放内存,内存都在自己控制范围内(特别是低RAM手机)
内存在自己管控范围内
=> 如场景:app内部从主界面跳转到别的界面,然后回到主界面过程中发现很多用量无法回到初始用量,内存就是增加了
除了上述在合适时候解除索引reference关系,还建议在适当的时候主动释放内存
最见效果的是1、2的方法,如果发现这部分大了,可以试一下,配合索引解除有很大可能回到用量初始状态
1、
Java heap
: System.gc();System.runFinalization();System.gc();
2、GL/EGL
: ThreadedRenderer.trimMemory(20或者80,80回收多一点,20影响小一点,按需求);(如果不行(上面80不行可以用下面的80)可以使用WindowManagerGlobal.getInstance().trimMemory(80);如果还是不行就直接调用ActivityThread的scheduleTrimMemory吧)
3、 Database: SQLiteDatabase.releaseMemory();
4、 font/image caches和text layout的回收:Canvas.freeCaches();Canvas.freeTextLayoutCaches();
ps:
本地调试回收GL/EGL使用的方法是adb指令的trimMemory,
adb shell am send-trim-memory --user -2 com.android.systemui 80;
注意需要改一下平台限制,不然adb指令不会执行
frameworks/base$ git diff
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d8243d1..4b4c4d8 121644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3117,12 +3117,12 @@ public class ActivityManagerService extends IActivityManager.Stub
throw new IllegalArgumentException("Process has no app thread");
}
if (app.mProfile.getTrimMemoryLevel() >= level) {
- throw new IllegalArgumentException(
+ Slog.w(TAG,
"Unable to set a higher trim level than current level");
}
if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
app.mState.getCurProcState() > PROCESS_STATE_IMPORTANT_FOREGROUND)) {
- throw new IllegalArgumentException("Unable to set a background trim level "
+ Slog.w(TAG, "Unable to set a background trim level "
+ "on a foreground process");
}
执行后可以看到EGL/GL的用量显著减少(当然这个方法对于launcher的使用要小心一点,不要回收launcher主界面这部分用量(其它用量可以回收,不是一刀切),如果回收,每次回到桌面都会变慢(主要是在低配置手机申请内存比较慢,高配置手机速度快影响就很小了),需要根据场景使用,注意使用时机,避免正在使用中触发回收,80不行的话20也可以)
** MEMINFO in pid 5312 [com.android.systemui] **
Pss Private Private SwapPss Rss Heap Heap Heap
Total Dirty Clean Dirty Total Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------
Native Heap 49388 49348 0 9601 51252 69136 45573 23562
Dalvik Heap 10733 9144 0 238 15376 19718 9859 9859
Dalvik Other 1901 1752 0 334 3312
Stack 1496 1496 0 684 1512
Ashmem 75 52 0 0 676
Other dev 12 4 8 0 476
.so mmap 6465 352 648 358 64056
.jar mmap 2343 0 0 0 34296
.apk mmap 18126 0 15340 0 26864
.ttf mmap 262 0 4 0 824
.dex mmap 18504 36 18444 12 19176
.oat mmap 698 0 0 0 16232
.art mmap 13024 12272 84 866 28228
Other mmap 105 8 68 0 968
EGL mtrack 2743 2743 0 0 2743
GL mtrack 1332 1332 0 0 1332
Unknown 980 972 0 182 1324
TOTAL 140462 79511 34596 12275 268647 88854 55432 33421