概述
原文:Investigating Your RAM Usage
因为Android是使用在移动设备上,因此必须时刻考虑应用使用了多少RAM。即使Dalvik与ART提供了垃圾回收机制,也并不意味着你能忽视应用何时分配、释放内存。为了在系统切换应用时提供稳定的用户体验,重要的是当用户没有与你的应用交互时,需要尽可能地减少应用的内存消耗。
即使你在开发中按照Managing Your App Memory中的最佳示例做了,可能还会造成内存泄漏或引入其它的内存问题。唯一能够确保应用使用尽可能少的内存的方法是使用工具分析应用内存的使用情况。
一、分析log信息:
分析应用内存使用情况最简单的方式是分析运行时log信息。当GC发生时,一些信息会打印到log上。当然设备监视器或者IDE(Eclipse与Android Studio)中的日志输出也非常有价值。
Dalvik日志信息:
Dalvik(非ART)中,每次GC时都会在logcat中打印如下信息:
D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_tim
e>
例如:
D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K,
paused 2ms+2ms
说明:
1.GC_Reason:指明什么引起了GC以及回收类型。可能是以下原因:
1) GC_CONCURRENT:当应用堆开始填充时就释放内存的一种并发GC
2) GC_FOR_MALLOC:当应用在堆已满的情况下继续分配内存会导致GC发生,此时系统会停止你的应用并
回收内存
3) GC_HPROF_DUMP_HEAP:当请求创建一个HRPOF文件来分析应用堆时反生的GC
4) GC_EXPLICIT:当调用gc()时出现的显示GC(尽量避免调用gc()而是使用系统的回收机制)
5) GC_EXTERNAL_ALLOC:这仅发生在api10及以下版本(10以上的版本将在Dalvik堆中分配所有的东西)
2.Amount_freed:GC回收内存的数量
3.Heap_stats:堆中空闲部分所占百分比以及存活对象的数量、堆总大小
4.External_memory_stats:在api10及以下版本中外部分配的内存
5.Pause_time:越大的堆需要越久的暂停时间。并发的暂停发生在两个地方:收集的开始与结束
随着log信息的累积,仔细查看堆的增长(上例中的3571K/9991K)。如果这个值支持增长,就表示你的应用可能出现了内存泄漏
ART日志信息:
与Dalvik不同,ART不会记录那些非显示请求的GC的日志信息。只有当GC被认定很慢时,其信息才会被打印。 更准确地说,GC的暂停时间超过5ms或GC的持续时间超过100ms。如果应用并非处于可被感知的暂停状态,它的 GC就不会被认定过慢。显示调用的GC信息始终会被打印。
ART日志包括如下信息:
I/art: <GC_Reason> <GC_Name> <Objects_freed>(<Size_freed>) AllocSpace Objects, <Large_objects_freed>(<Large_object_size_freed>) <Heap_stats> LOS objects, <Pause_time(s)>
示例:
I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects, 21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms
示例:
1.GC_Reason:指明什么引起了GC以及回收类型。可能是以下原因:
1) Concurrent:并发的GC,不会暂停应用的线程。此GC运行在后端线程并且不会阻碍内存分配
2) Alloc:此GC将在应用在堆已满情况下继续分配内存的时候出现。这种情况下,GC将出现在内存分配
的线程
3) Explicit:此GC是被应用显式请求的,如通过调用gc()。与Dalvik相同,ART中同样建议你使用系统
的GC,尽可能避免显示请求GC。显示的GC是阻碍式的,因为它们将阻塞内存分配线程并并占据非必
须的CPU周期。当显示的GC造成其他线程取得优先权的时,可能会造成内存抖动
4) NativeAlloc:此信息是由于本地代码内存分配造成地本地内存压力引起的,如Bitmaps或
RenderScript分配对象
5) CollectorTransition:这种情况是由于堆转换引起的。它是因在运行时切换GC导致的。
Collector transitions由将全部对象从一个自由列表支持空间复制到一个凹凸指针空间(或相反)
构成。当前的collector transitions仅当应用改变进程状态在低RAM设备上从可察觉暂停状态变为
不可察觉暂停状态或相反)时出现
6) HomogeneousSpaceCompact:Homegeneous space compaction是自由列表空间到自由列表压缩空间 ,
这通常出现在应用转变为可察觉暂停进程状态时。做这些的主要原因是减少RAM使用并整理堆碎片
7) DisableMovingGc:这并非真实的GC reason,仅是使用GetPrimitiveArrayCritical造成回收阻塞时
的提醒(在进行并发的堆压缩时)。通常,使用GetPrimitiveArrayCritical是非常不推荐的,这是因
为它在移动回收者时有限制。
8) HeapTrim:这并非是GC reason,仅是当堆裁剪结束前GC阻塞的提醒。
2.GC_Name:ART有各种不同的可运行的GC:
1) Concurrent mark sweep (CMS):一个完整的堆回收器,回收除图像空间外全部的空间
2) Concurrent partial mark sweep:一个几乎完整的堆回收器,回收除图像、zygote空间外所有的空
间
3) Concurrent sticky mark sweep:分代的回收器,它只能回收上次GC后新分配的对象。此垃圾回收
器比前两种回收器运行的频繁,因为它更快并且暂停时间更短
4) Marksweep + semispace:一种非并发、复制的GC用于堆转换(如齐性空间压缩-清理堆中的碎片)
3.Objects_freed:本次GC从非大对象空间中回收的对象数量
4.Size feed:本次GC从非大对象空间回收的字节数
5.Large objects freed:本次GC从大对象空间中回收的对象数
6.Large object size freed:本次GC从大对象空间中回收的字节数
7.Heap stats:空闲空间的百分比以及(活跃对象数、堆总大小)
8.Pause times:一般来说pause times是与GC运行时改变的对象引用的数量成比例的。当前,ART CMS GC只
在接近GC结 束时有一次暂停。移动的GC需要较长的暂停,需要与GC改变的持续时间一致。
如果你在log中看到大量的GC,查找堆中增长的部分(上例中的25MB/38MB)。如果此值一直增加并且没有变小
的趋势,就表明应用可能出现了内存泄漏。此外,当你看到GC的reason是"Alloc"时,此时你可能就接近堆的
最大容量并且不久后就会出现OOM。
二、查看堆更新:
可以在Android Studio的HPROF视图或Device Monitor中查看应用堆的实时信息以获得应用何时使用内存以及
使用了何种内存。
1.Andorid Studio中的内存监控器:
使用Android Studio查看应用内存使用情况:
1) 在虚拟器或已连接设备上运行应用
2) 打开Android实时窗口,在内存监控器中查看释放以及分配的内存
3) 在内存监控器的toolbar中点击Dump Java Heap图标()。Android Studio将在Capture选项卡中创
建堆快照文件(命名格式Snapshot-yyyy.mm.dd-hh.mm.ss.hprof)
4) 双击heap snapshot文件以打开HPROF视图。(注意:为了将堆转存为AndroidStudio中标准的HPROF格
式,在Captures视图中右击heap snapshot并选择Export to standard .hprof。
5) 操作应用并点击()图标来引起堆分配。
6) 鉴别应用的哪些行为可能导致太多的内存分配并决定应用中的哪些部分需要尝试减少分配以及释放资
源。
如下图:
2.设备监视器:
1) 打开设备监视器:从<sdk>/tools/目录中打开monitor工具
2) 在Debug窗口中,在左侧列表中选择你的应用进程
3) 点击进程列表上方的Update Heap
4) 在右侧的表盘中,选择Heap标签页
说明:Heap视图显示一些应用推内存使用的基本信息,并且在每次GC后都会刷新。可以点击Cause GC按钮查看第一次更新。
[1]Update Heap、[2]Cause GC按钮。右侧Heap标签页显示结果
继续操作你的应用以查看每次垃圾回收后的堆分配的更新信息。这些信息可以帮助你鉴别应用的哪些行为可能导致太多的内存分配并决定应用中的哪些部分需要尝试减少分配以及释放资源
最后
以上就是跳跃黄蜂为你收集整理的Investigating Your RAM Usage(一)一、分析log信息:二、查看堆更新:的全部内容,希望文章能够帮你解决Investigating Your RAM Usage(一)一、分析log信息:二、查看堆更新:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复