1. Android APP memory用量都有哪些2. Native Heap的用量分析3. Dalvik Heap的用量分析4. mmap的用量分析5.EGL/GL mtrack的用量分析6. 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:这个是显示相关的一些用量
在性能问题分析方法[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/productsymbols > 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/productsymbols > backtrace_heap.html
2、使用Android Studio profile的Native Size + reference也可以找到一部分native heap的内容(下图gms core的hprof文件用Android Studio打开,此处紧急说明Native Size、reference分别在哪个位置)
这个也可以参考性能问题分析方法[1] --- RAM,
此处注意一下建议使用Android Studio的profile和MemoryAnalyzer 2个工具结合分析,分析出来的综合对比
这个使用adb shell showmap +pid形式加上xlsx的排序,大概你就知道是什么载入app导致用量高了
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 339726. Memory用量如何及时回收
我们除了关注索引关系,还需要关注如何尽快释放内存,内存都在自己控制范围内(特别是低RAM手机)
内存在自己管控范围内
=> 如场景:app内部从主界面跳转到别的界面,然后回到主界面过程中发现很多用量无法回到初始用量,内存就是增加了
除了上述在合适时候解除索引reference关系,还建议在适当的时候主动释放内存
最见效果的是1、2的方法,如果发现这部分大了,可以试一下,配合索引解除有很大可能回到用量初始状态
1、 Java heap: System.gc();System.runFinalization();System.gc();
2、 GL/EGL: ThreadedRenderer.trimMemory(TRIM_MEMORY_COMPLETE);
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主界面这部分用量(其它用量可以回收,不是一刀切),如果回收,每次回到桌面都会变慢(主要是在低配置手机申请内存比较慢,高配置手机速度快影响就很小了),需要根据场景使用)
** 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 ```java
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)