如何检查 Android 应用的内存使用情况

注意:本篇文章是本人阅读相关文章所写下的总结,方便以后查阅,所有内容非原创,侵权删。

本篇文章内容来自于:
如何检查 Android 应用的内存使用情况

目录

  1. 解析日志信息logcat
  2. 使用DDMS查看堆的更新Heap
  3. 使用DDMS跟踪内存分配Allocation Tracker
  4. 查看总体内存分配 adb

1. 解析日志信息logcat

//GC_CONCURRENT GC原因

//freed 2049K 释放数量 执行垃圾回收后内存释放的数量

//65% free 3571K/9991K 堆状态 空闲的百分比和(活动对象的数量)/(总的堆大小)。

//external 4703K/5261K 外部内存状态 
//API 10和更低版本中的外部分配的内存(分配的内存大小)/(回收发生时的限制值)。

//paused 2ms+2ms 暂停时间
//越大的堆的暂停时间就越长。并发回收暂停时间分为两部分:一部分在回收开始时,另一部分在回收将近结束时。
D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms

GC原因 触发垃圾回收执行的原因和垃圾回收的类型。

  • GC_CONCURRENT
    并发垃圾回收,当堆开始填满时触发来释放内存。
  • GC_FOR_MALLOC
    堆已经满了时应用再去尝试分配内存触发的垃圾回收,这时系统必须暂停应用运行来回收内存。
  • GC_HPROF_DUMP_HEAP
    创建HPROF文件来分析应用时触发的垃圾回收。
  • GC_EXPLICIT
    显式垃圾回收,例如当调用gc()(应该避免手动调用而是要让垃圾回收器在需要时主动调用)时会触发。
  • GC_EXTERNAL_ALLOC
    这种只会在API 10和更低的版本(新版本内存都只在Dalvik堆中分配)中会有。回收外部分配的内存(例如存储在本地内存或NIO字节缓冲区的像素数据)。

随着这些日志消息的增多,注意堆状态(上面例子中的3571K/9991K)的变化。如果值一直增大并且不会减小下来,那么就可能有内存泄露了。

2. 使用DDMS查看堆的更新

具体操作看android IDE——通过DDMS查看app运行时所占内存情况

2851519-235ff3e281d56b36.png

如何知道程序内存泄漏?
Heap视图中有一行数据是叫data object,即数据对象。它是我们app中大量存在的类类型的对象。
在data object中有一列 Total Size ,它的值就是当前进程中所有java对象的内存总量。
一般情况下,这个值决定是否内存泄漏。

如何判断?
1,不断的操作你的app,同时观察Total Size的值。
2,Total Size的值一般会稳定在一个正常范围内。
3,当我们在不断操作app的时候,内存会有一个先增加(不断的生成对象),后下降(对象被回收)。如果程序的代码处理良好,那么内存占用量会有一个明显的回落,并且稳定在一个正常水平。
4,如果你的代码没有很好的释放内存。那么,内存占用量就没有一个明显的回落,并且会越来越高,最终达到上限程序被kill掉。

3. 使用DDMS跟踪内存分配Allocation Tracker

当要减少内存问题时,应该使用Allocation Tracker来更好的了解内存消耗大户在哪分配。Allocation Tracker不仅在查看内存的具体使用上很有用,也可以分析应用中的关键代码路径,例如滑动。

例如,在应用中滑动列表时跟踪内存分配,可以看到内存分配的动作,包括在哪些线程上分配和哪里进行的分配。这对优化代码路径来减轻工作量和改善UI流畅性都极其有用。


2851519-1f0591085cb76e67.jpg

使用Allocation Tracker:
1.打开Device Monitor 。
从<sdk>/tools/路径下加载monitor工具。
2.在DDMS窗口,从左侧面板选择应用进程。
3.在右侧面板中选择Allocation Tracker标签页。
4.点击Start Tracking。
5.执行应用到需要分析的代码路径处。
6.点击Get Allocations来更新分配列表。

4. 查看总体内存分配 adb

adb命令行:

adb shell dumpsys meminfo <package_name>

输出结果:
应用当前的内存分配输出列表,单位是千字节。

appledeMBP:~ apple$ adb shell dumpsys meminfo com.example.apple.encryptiondemo
Applications Memory Usage (in Kilobytes):
Uptime: 1305554068 Realtime: 5441384153

** MEMINFO in pid 22196 [com.example.apple.encryptiondemo] **
                   Pss  Private  Private  SwapPss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap    11162    11076        0        0    20480    12670     7809
  Dalvik Heap    14090    13872        0        0    33928    25736     8192
 Dalvik Other     1196     1192        0        0                           
        Stack      356      356        0        0                           
       Ashmem        2        0        0        0                           
      Gfx dev    13210    11740        0        0                           
    Other dev        4        0        4        0                           
     .so mmap     4927      148     3796        0                           
    .jar mmap        0        0        0        0                           
    .apk mmap     2713     2672        0        0                           
    .ttf mmap       19        0        0        0                           
    .dex mmap      144       12       72        0                           
    .oat mmap     1910        0        0        0                           
    .art mmap     1655     1200       28        0                           
   Other mmap       10        4        0        0                           
   EGL mtrack     2764     2764        0        0                           
    GL mtrack     3644     3644        0        0                           
      Unknown      359      356        0        0                           
        TOTAL    58165    49036     3900        0    54408    38406    16001
 
 App Summary
                       Pss(KB)
                        ------
           Java Heap:    15100
         Native Heap:    11076
                Code:     6700
               Stack:      356
            Graphics:    18148
       Private Other:     1556
              System:     5229
 
               TOTAL:    58165       TOTAL SWAP PSS:        0
 
 Objects
               Views:       20         ViewRootImpl:        1
         AppContexts:        4           Activities:        1
              Assets:       16        AssetManagers:        2
       Local Binders:       13        Proxy Binders:       20
       Parcel memory:        3         Parcel count:       15
    Death Recipients:        2      OpenSSL Sockets:        0
            WebViews:        0
 
 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0

私有(Clean and Dirty) 内存
进程独占的内存。也就是应用进程销毁时系统可以直接回收的内存容量。
通常来说,“private dirty”内存是其最重要的部分,因为只被自己的进程使用。它只在内存中存储。

实际使用内存 (PSS)
另一种应用内存使用的计算方式,把跨进程的共享页也计算在内。
把所有进程的PSS值加起来就可以确定所有进程总共占用的内存

更多看如何检查 Android 应用的内存使用情况

猜你喜欢

转载自blog.csdn.net/weixin_34219944/article/details/87229096