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 Sizereference分别在哪个位置)
在这里插入图片描述

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值