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

Android是为移动设备而设计的,所以应该关注应用的内存使用情况。尽管Android的Dalvik虚拟机会定期执行垃圾回收操作,但这也不意味着就可以忽视应用在何时何处进行内存分配和释放。为了提供良好的用户体验,做到系统在不同应用间流畅切换,当用户和应用无交互时,避免应用不必要的内存消耗是很重要的。

尽管在开发过程中很好的遵守了《管理应用内存》(ManagingYourAppMemory)中的原则(也是应该遵守的),仍然可能会有对象泄露或引入其他的内存bug。对此的安全性,可以采取的措施就是Android代码加密,本地数据保护等一系列安全的加密技术。想详细了解的可以关注下爱加密,专业的移动应用安全智能服务提供商!唯一来确定应用使用了尽可能少的内存的方法,就是使用工具来分析应用的内存使用情况。

解析日志信息

最简单的调查应用内存使用情况的地方就是Dalvik日志信息。可以在logcat(输出信息可以在DeviceMonitor或者IDE中查看到,例如Eclipse和AndroidStudio)中找到这些日志信息。每次有垃圾回收发生,logcat会打印出带有下面信息的日志消息:

D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>

GC原因

触发垃圾回收执行的原因和垃圾回收的类型。原因主要包括:

GC_CONCURRENT

并发垃圾回收,当堆开始填满时触发来释放内存。

GC_FOR_MALLOC

堆已经满了时应用再去尝试分配内存触发的垃圾回收,这时系统必须暂停应用运行来回收内存。

GC_HPROF_DUMP_HEAP

创建HPROF文件来分析应用时触发的垃圾回收。

GC_EXPLICIT

显式垃圾回收,例如当调用(应该避免手动调用而是要让垃圾回收器在需要时主动调用)时会触发。

GC_EXTERNAL_ALLOC

这种只会在API10和更低的版本(新版本内存都只在Dalvik堆中分配)中会有。回收外部分配的内存(例如存储在本地内存或NIO字节缓冲区的像素数据)。

释放数量

执行垃圾回收后内存释放的数量。

堆状态

空闲的百分比和(活动对象的数量)/(总的堆大小)。

外部内存状态

API10和更低版本中的外部分配的内存(分配的内存大小)/(回收发生时的限制值)。

暂停时间

越大的堆的暂停时间就越长。并发回收暂停时间分为两部分:一部分在回收开始时,另一部分在回收将近结束时。

例如:

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms

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

查看堆的更新

为了得到应用内存的使用类型和时间,可以在DeviceMonitor中实时查看应用堆的更新:

1.打开DeviceMonitor。

从<sdk>/tools/路径下加载monitor工具。

2.在DebugMonitor窗口,从左边的进程列表中选择要查看的应用进程。

3.点击进程列表上面的UpdateHeap。

4.在右侧面板中选择Heap标签页。

Heap视图显示了堆内存使用的基本状况,每次垃圾回收后会更新。要看更新后的状态,点击GauseGC按钮。

图1.DeviceMonitor工具显示[1]UpdateHeap和[2]CauseGC按钮。右边的Heap标签页显示堆的情况。

跟踪内存分配

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

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

使用AllocationTracker:

1.打开DeviceMonitor。

从<sdk>/tools/路径下加载monitor工具。

2.在DDMS窗口,从左侧面板选择应用进程。3.在右侧面板中选择AllocationTracker标签页。4.点击StartTracking。5.执行应用到需要分析的代码路径处。6.点击GetAllocations来更新分配列表。

列表显示了所有的当前分配和512大小限制的环形缓冲区的情况。点击行可以查看分配的堆栈跟踪信息。堆栈不只显示了分配的对象类型,还显示了属于哪个线程哪个类哪个文件和哪一行。

图2.DeviceMonitor工具显示了在AllocationTracker中当前应用的内存分配和堆栈跟踪的情况。

注意:总会有一些分配是来自与DdmVmInternal和allocationtracker本身。

尽管移除掉所有严重影响性能的代码是不必要的(也是不可能的),但是allocationtracker还是可以帮助定位代码中的严重问题。例如,应用可能在每个draw操作上创建新的Paint对象。把对象改成全局变量就是一个很简单的改善性能的修改。

查看总体内存分配

为了进一步的分析,,查看应用内存中不同内存类型的分配情况,可以使用下面的adb命令:

adb shell dumpsys meminfo <package_name>

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

当查看这些信息时,应当熟悉下面的分配类型:

私有(CleanandDirty) 内存

泪,一种痛苦的雨滴,不知从什么时候开始已在我的世界下个不停。

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

相关文章:

你感兴趣的文章:

标签云: