如何使用androidstudio的使用-studio以及DDMS进行内存泄漏和抖动测试

5278人阅读
Android(4)
  本文在腾讯技术推文上 修改 发布。  
  自从Google在2013年发布了Android Studio后,Android Studio凭借着自己良好的内存优化,酷炫的UI主题,强大的自动补全提示以及Gradle的编译支持正逐步取代Eclipse,成为主流的Android开发IDE。Android Studio在为我们提供了良好的编码体验的同时,也提供了许多对App性能分析的工具,让开发者可以更方便分析App性能。Google在IO大会上一直告诫开发者不要无节制的使用手机内存,要注意一些不良的开发习惯会导致App的内存泄漏。虽然如今网上检测App内存泄漏的文章汗牛充栋,但是要使用DDMS和MAT,不仅使用步骤复杂繁琐,而且要手动排查内存泄漏的位置,操作起来多有不便。其实Android
Studio已经开始支持自动进行内存泄漏检查了,本文就带着大家一探其中的奥妙吧。
什么是内存泄漏
  这个也是个面试常客,通俗来说,定义了的变量没使用,就是内存泄漏了。Android虚拟机的垃圾回收采用的是根搜索算法,还一种是程序计数器算法。GC会从根节点(GC Roots)开始对heap进行遍历。到最后,部分没有直接或者间接引用到GC Roots的就是需要回收的垃圾,会被GC回收掉。而内存泄漏出现的原因就是存在了无效的引用,导致本来需要被GC的对象没有被回收掉。
mLeak是存储在静态区的静态变量,而Leak是内部类,其持有外部类Activity的引用。这样就导致Activity需要被销毁时,由于被mLeak所持有,所以系统不会对其进行GC,这样就造成了内存泄漏。
再举一个最常犯的例子
  如果我们在在调用Singleton的getInstance()方法时传入了Activity。那么当instance没有释放时,这个Activity会一直存在。因此造成内存泄露。
解决方法可以将new Singleton(context)改为new Singleton(context.getApplicationContext())即可,这样便和传入的Activity没关系了。
内存泄漏的检测
  打开Android Studio,编译代码,在模拟器或者真机上运行App,然后点击,在Android Monitor下点击Monitor对应的Tab,进入如下界面
  在Memory一栏中,可以观察不同时间App内存的动态使用情况,点击可以手动触发GC,点击可以进入HPROF
Viewer界面,查看Java的Heap,如下图
  Reference Tree代表指向该实例的引用,可以从这里面查看内存泄漏的原因,Shallow Size指的是该对象本身占用内存的大小,Retained Size代表该对象被释放后,垃圾回收器能回收的内存总和。
下面我们以掌上道聚城客户端为例,来一探内存泄漏检测的方法。
  打开Android Studio,编译代码,运行掌上道聚城,然后开始尽情的耍我们的App啦,然后就从Memory Monitor里面观察App的内存使用曲线,突然发现,纳尼!!!怎么内存使用越来越大了,这就很有可能是发生内存泄漏了,然后点击手动进行GC,再点击观看JavaHeap,点击Analyzer
Task,Android Monitor就可以为我们自动分析泄漏的Activity啦,分析出来如下图所示
  在Reference Tree里面,我们直接就可以看到持有该Activity的单例对象,直接定位到该单例中的代码,发现代码中出现了
  和刚刚举得例子里出现的错误一模一样,我们修复了检查出的内存泄漏的问题,并将修复前和修复后的代码在相同的模拟器上运行并进行相同的操作,查看他们使用内存的情况,如下图所示
有内存泄漏的情况,占用内存约为43M
&  修复了内存泄漏问题,占用内存为36M在修复了内存泄漏问题后,内存使用下降了16.3%!!!
最后补充一个我遇到的例子
优化代码后,明显解决了上述问题
最后,在掌握了Android Monitor的使用方法后,相信能在android开发的路上助各位一臂之力。
如果您认为这篇文章还不错或者有所收获,您可以通过扫描一下下面的支付宝二维码 打赏我一杯咖啡【物质支持】,也可以点击右下角的【推荐】按钮【精神支持】,因为这两种支持都是我继续写作,分享的最大动力
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:26413次
排名:千里之外
原创:24篇
转载:73篇
(1)(3)(8)(3)(27)(3)(6)(4)(20)(2)(20)检测和解决Android应用的性能问题
发表于 09:50|
来源code.tutsplus|
作者Jessica Thornsby
摘要:开发者在忙碌于构建精美的用户界面或完成新的特性时,很容易忘记性能相关的事情。本文作者就解决Android应用性能问题给出了三个方面,即过度绘制、Android图形渲染以及Memory Leaks内存泄漏。
3. Memory Leaks 内存泄漏
步骤1:问题描述
Android是一个自动管理内存的开发环境,不要让这个句话蒙蔽了,因为内存泄漏依旧是可能发生的。这是因为垃圾回收器只会移除那些不可达的对象。如果它不是一个不可达的对象,那么该对象就不会被释放掉。
这些不可达的对象阴魂不散,聚集在你的堆内存中,占用App的内存控件。如果你继续泄漏对象,那么可用的内存空间将会越来越小,GC操作就会频繁触发。
有两个原因表明这是一个坏消息。首先,GC操作通常不会明显地影响你的App性能,但是当内存控件较小时大量的GC操作会使你的App变慢,此时UI就不会那么流畅了。第二问题是移动设备的内存空间相对来说较小,因此内存泄漏会快速地升级为内存溢出,导致应用Crash。
内存泄漏难以被检测出。可能只有当用户开始抱怨你的应用时你才能发觉内存泄漏问题。幸运地是,Android SDK提供了一些有用的工具来让你找到这些问题。(译者注
: Square的开源库LeakCanary是查找内存泄漏的优秀工具,强烈建议大家使用)。
步骤2 : 内存监视器 (Memory Monitor)
Memory Monitor是一个能够实时获取应用内存使用情况的工具。需要注意的是这个工具只能作用于正在运行的应用,因此确保你的要测试的应用已经安装到你的设备中,并且你的设备已经连接到你的电脑上。
Memory Monitor已经内置在Android Studio中,因此你可以点击Android Studio的底部的”Memory”这个tab来切换到内存监视页面。当你切换到该页面的时候,Memory
Monitor就开始记录你的内存使用情况了。
如果Memory Monitor没有开始记录,那么确保你的设备是已经被选中的状态。
如果Memory Monitor提示No debuggable applications,那么你可以打开Android Studio的”Tools”菜单,选择”Android”,然后确保选中了Enable
adb integration。这个功能还不是很稳定,所以有时候你需要手动切换它的状态。你也可以断开设备与电脑的连接,然后再重连,这样可能就OK了。
一旦Memory Monitor检测到正在运行的应用,它就会显示这个应用的内存使用情况。已使用的内存会被表示为深蓝色,未分配的内存则会变为浅蓝色。
花一些时间与你的设备交互,并且关注你的内存使用情况。最终已分配的内存会增长,直到没有内存可用。此时,系统就会释放触发GC释放内存,当你看到已分配的内存明显的下降时就代表GC操作被触发了。
GC通常情况下会将无用的内存释放掉,但是当你看到App在短时间内快速增长或者GC变得非常频繁,此时你就需要倍加小心了,这就是发生内存泄漏的信号!
如果你通过Memory Monitor来追踪一个可疑的内存泄漏问题,你可能会看到Android系统会为你的App增大可用内存,TODO :
最终,你可能会看到你的App消耗了非常多的内存以至于系统无法再给你的应用更多的可用内存。如果你看到这种场景,那么说明你在内存使用上犯了很严重的错误。
步骤3 : Android Device Monitor
另一个能够帮助你收集更新关于内存泄漏信息和其他内存相关问题的工具是Android Device Monitor的DDMMS工具下的Heap。
Heap工具能够通过显示系统为你分配了多少内存来帮助你诊断内存泄漏问题。正如上面提到的,如果已分配的内存不断地增长,那么这是发生内存泄漏的明显信号。
但是这个工具还提供了许多关于你的应用堆内存使用情况的数据,包含你的App内分配的各种对象、分配的对象数量以及这些对象占用了多少空间。这些额外的信息对于你追踪内存泄漏极为有用。
你可以在Android Device Monitor工具中选择DDMS,在Devices中选择你要检测的App。然后选择Heap标签,如图所示。然后花一些时间与你的App进行交互以收集内存信息。
heap输出信息会在GC事件之后,因为你可以手动点击Cause GC来触发GC,使得Heap内存数据尽快地显示出来。
一旦GC事件被触发了,heap标签下就会更新App的堆内存使用信息,这些信息会在每次GC时更新。
在这篇文章中,我们学习了一些开发中最常见的性能问题,过度绘制、内存泄漏、缓慢的UI渲染。
相信你已经掌握了如何使用工具来检查这些问题,以及如何获取更新的信息来判断你的应用中是否出现了这些性能问题。你有越多的信息,就越容易追踪到问题的原因并且修复它。
Android SDK有很多工具可以供你诊断和定位性能问题。如果你想学习更多这方面的知识,你可以访问u这两篇官方文档和。
文章来源:,译文出自:。译者简介:何红辉(Mr.Simple),资深Android工程师,开发技术前线项目站长,现就职于友盟,负责友盟社会化组件、微社区的研发工作。
第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。&
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章Android程序的内存泄漏与规避方法-嵌入式系统-与非网
  应用程序中内存使用的问题经常容易被忽视,在传统的编程语言中(例如C语言),回收内存的任务是由程序本身来完成的,程序可以显式分配和释放变量所占用的内存。Android[1]应用程序采用Java编程语言编写,而Java区别于其他语言的一个重要优点就是它通过垃圾收集器(Garbage Collection,GC) 自动管理内存的回收,Java程序员只需通过内存分配操作创建对象,而无须关心对象占用的空间是如何被收回的。因此很多程序员认为在Java中不必担心的问题,然而实际并非如此,Java中仍然存在着内存泄漏。Android应用程序运行在嵌入式系统中,而嵌入式系统中内存的总量非常有限,因此如何合理地规避&内存泄露&问题也就显得十分关键。
1 造成Android应用程序内存泄漏的原因
  1.1 引用没释放造成的内存泄露
  (1) 注册没有取消造成的内存泄漏
  这种Android的内存泄露比纯Java的内存泄漏还要严重,因为其他一些Android程序可能引用系统的Android程序的对象(比如注册机制)。即使Android程序已经结束了,但是别的应用程序仍然还有对Android程序的某个对象的引用,泄漏的内存依然不能被垃圾回收。
  (2) 集合中对象没有关闭造成的内存泄漏
  通常把一些对象的引用加入到了集合中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,慢慢地这个集合就会越来越大。如果这个集合是静态的话,那情况就会更严重。
  1.2 资源对象没有关闭造成的内存泄漏
  资源对象比如Cursor、File文件等往往都用了一些缓冲,在不使用的时候应该及时关闭它们,以便它们的缓冲及时回收内存。这些缓冲不仅存在于Java虚拟机内,还存在于Java虚拟机外,如果仅仅是把它的引用设置为空,而不关闭它们,那么往往会造成内存泄漏。
  一些不良代码造成的内存压力原因如下:
◆ Bitmap没有调用recycle( );
◆ 构造Adapter时,没有使用缓存的convertView;
◆ ThreadLocal使用不当;
2 内存泄漏的检测及定位
2.1 内存泄漏的检测
  Android应用程序是基于虚拟机的,其内存管理都是由Dalvik[2]代为管理,GC的回收不是及时的。一个正常的应用程序在其运行稳定后其内存的占用量是基本稳定的,不应该是无限制的增长。同样,对任何一个类的对象的使用个数也有一个相对稳定的上限,不应该是持续增长的。当我们持续地观察某个应用程序运行过程中使用内存的大小和各实例的个数时,如果内存的大小持续增长,则说明系统存在内存泄漏的问题;如果特定类的实例对象个数随时间而增长,则说明这个类的实例可能存在泄漏情况。比如一个Activity被关掉之后,其内存的引用对象会在下次GC回收[3]的时候通过回收算法计算,如果这部分内存已经属于可回收的对象,那么这些垃圾对象会被一并回收,内存未泄漏趋势图如图1所示。
图1 内存未泄漏趋势图
  内存泄漏趋势图如图2所示。在重复打开关闭某个应用程序的时候,内存一直在向上爬升,也就是说每次关闭这个Activity的时候,有些应该释放的内存并没有被释放掉。由此我们可以确定这个应用程序存在着内存泄漏的问题。
图2 内存泄漏趋势图
2.2 内存泄漏的位置定位
  查找内存泄漏一种比较彻底的方法就是代码走查,我们可以一行一行地分析对象的创建去留等等[4],但会很耗时间也比较迷茫。这里可以通过Eclipse Memory Analyzer Tool(MAT)工具来定位内存泄漏的位置,该方法只适用于Java层的查找,对C/C++没用,也就是说只针对于被虚拟机来管理的进程和内存。MAT的解析文件是.hprof文件,这个文件里面存放了某进程的内存快照,MAT通过解析.hprof文件就会自动生成一个内存泄漏推测报告,通过分析这个报告就可以准确定位到有可能存在内存泄漏的具体位置。
  然而,还有一些内存泄漏通过MAT是查不出来的,比如native的代码,对C/C++是无能为力的,对于这些问题本文并没有做过多的研究。
3 规避内存泄漏的方法
  在编写应用程序的过程中,对于BraodcastReceiver、ContentObserver、FileObserver在Activity onDestory或者某类声明周期结束之后一定要注销掉,否则这个Activity类会被系统强引用,不会被内存回收。
  在定义成员变量时,不要直接对Activity进行引用而作为成员变量。如果不得不这么做,那么可以用private Weak Reference &Activity&mActivity来声明。同样,对于Service等其他有自己声明周期的对象来说,直接引用都需要谨慎考虑是否会存在内存泄漏的可能。&
  在应用程序中,很多内存泄漏是由于循环引用而造成的,比如a中包含了b,b中包含了c,c中又包含a,这样只要一个对象存在,那么其他对象肯定会一直常驻内存。因此,在编写应用程序时要从逻辑上来分析是否需要这样的设计。
  Bitmap对象不再使用时,调用recycle()方法释放内存。如果一个Bitmap对象比较占内存,当它不再被使用的时候,可以调用Bitmap.recycle()方法回收此对象的像素所占用的内存,这个不是必须的,可视情况而定。
  还要注意释放对象的引用。当一个生命周期较短的对象A,被一个生命周期较长的对象B保有其引用的情况下,在A的生命周期结束时,要在B中清除掉对A的引用。
4 内存监测工具DDMS和内存分析工具MAT
4.1 内存监测工具DDMS
  我们在开发Android应用程序时,很容易造成内存的泄漏,这时需要一些工具来帮助我们检查代码中是否存在会造成内存泄漏的不良代码。在Android tools的DDMS里面带有一个内存监测工具Heap,用它来监测应用程序使用内存的情况,这里需要和Eclipse配合使用。利用 Heap工具监测应用进程使用内存情况的方法如下:&
① 首先启动Eclipse,切换到DDMS透视图,并确认Devices视图、Heap视图都已打开。将要测试的设备(比如手机)通过USB数据线连接到电脑上,连接成功后,会在DDMS的Devices视图界面中显示手机设备的序列号,以及设备中正在运行的部分进程信息。
② 然后选中想要监测的进程,比如system_process进程,进而选中Devices视图界面中最上方一排图标中的&Update Heap&图标,点击Heap视图中的&Cause GC&按钮,此时在Heap视图中就会看到当前选中的进程的内存使用量的详细情况。
③ Heap视图界面会定时地刷新正在监测的进程内存使用情况,通过不断地操作被监测的应用程序来观察内存使用的变化。
  那么如何才能知道被监测的应用程序是否存在内存泄漏呢?这里需要注意一个值:Heap视图中有一个类型值叫做data object,即数据对象。在data object一行中有一列是&Total Size&,其值就是当前进程中所有Java数据对象的内存总量。一般情况下,这个值的大小决定了应用程序是否存在内存泄漏。我们不断地操作当前应用,同时注意观察data object的Total Size值,正常情况下Total Size的值都会稳定在一个有限的范围内,也就是说由于程序中的代码良好,没有造成对象不被垃圾回收的情况,内存占用量保持在了一个相对稳定的水平;反之,如果代码中存在没有释放对象引用的情况,则data object的Total Size值会随着操作次数的增多越来越大,直到到达一个上限后导致进程被杀掉。
  通过上面的分析,使用DDMS的Heap视图工具可以很方便地确认应用程序是否存在内存泄漏的问题。
4.2 内存分析工具MAT
  通过DDMS工具可以判断应用程序中是否存在内存泄漏的问题,那又如何定位到具体出现问题的代码片段,最终找到问题所在呢?内存分析工具MAT Memory Analyzer Tool解决了这一难题。MAT工具是一个Eclipse 插件,同时也有单独的RCP 客户端,MAT工具的解析文件是.hprof,这个文件存放了某进程的内存快照。MAT工具定位内存泄漏具体位置的方法如下:
① 生成.hprof文件。Eclipse中生成.hprof文件的方法有很多,不同Android版本中生成.hprof的方式也稍有差别,但它们整体思路是一样的。我们在DDMS界面选中想要分析的应用进程,在Devices视图界面上方的一行图标按钮中,同时选中&Update Heap&和&Dump HPROF file&两个按钮,这时DDMS将会自动生成当前选中进程的.hprof文件。
② 将.hprof 文件导入到MAT工具中,MAT工具会自动解析并生成报告,点击&Dominator Tree&按钮,并按包分组,选择已定义的包类点右键,在弹出的菜单中选择List objects?﹥With incoming references,这时会列出所有可疑的类。右键点击某一项,并选择Path to GC Roots?﹥exclude weak/soft references,MAT工具会进一步筛选出跟程序相关的所有内存泄漏的类。这样就可以追踪到某一个产生内存泄漏的类的具体代码中。&
  使用MAT内存分析工具查找内存泄漏的根本思路是找到哪个类的对象的引用没有被释放,然后分析没有被释放的原因,最终定位到代码中哪些片段存在着内存泄漏。
  Android应用程序中内存泄漏是一个特别重要但又难以解决的问题,不再有用的对象被其他依然有用的对象所引用是导致内存泄漏的主要原因。程序员良好的编程风格和专业的检测工具可以有效地减少内存泄漏的问题,比如上面介绍的内存监测工具DDMS和内存分析工具MAT。但如何更好地避免甚至消除内存泄漏、如何解决因内存泄漏而导致的Android应用程序系统性能下降问题,将是内存泄漏相关领域的重要研究方向。
关注与非网微信 ( ee-focus )
限量版产业观察、行业动态、技术大餐每日推荐
享受快时代的精品慢阅读
移动支付的普及令智能手机逐步取代了钱包的作用,行走在北上广深这样的一线城市,只携带一部手机也能平安的的过上一天。
发表于: 10:49:06
北京地铁官方微博今日发布通知:北京地铁将刷手机乘车服务扩展至全线路,用户只要开通手机一卡通,即可享受一部手机畅行北京地铁。
发表于: 11:00:37
Tecno是一个在非洲之外几乎没有任何知名度的Android智能手机品牌,其产品是由位于中国深圳的传音控股有限公司(以下简称“传音”)设计的。
发表于: 11:16:52
在全新的诺基亚品牌Android手机中,诺基亚3是最低端的产品。它在英国售价为120英磅(约合人民币1053元),但用户必须为这一低价格作出相当大牺牲。
发表于: 09:59:45
谷歌Android系统之父Andy Rubin之前发布了一款名叫Essential Phone的智能手机,不过这款备受关注的智能手机现在已经过了当初承诺的交货日期,并且Essential公司始终没有给予任何说法。
发表于: 13:25:27
集邦咨询半导体研究中心(DRAMeXchange)调查显示,第二季全球智能手机市场买气虽然依旧低迷,但相较于第一季因生产计划大幅下修导致的高库存水位,第二季已明显收敛并开始重启拉货。
发表于: 15:21:59
随着更多业者进入MRAM市场,STT执行长Barry Hoberman在日前受访时谈到了MRAM带来的商机及其可能取代现有主流存储器技术的未来前景。
发表于: 09:35:45
前两期《中国芯势力》介绍了长江存储和晋华存储,然而中国三大存储器势力还有一大神秘“队伍”——合肥长鑫,看看背后有着怎么样的神秘。
发表于: 11:09:00
今年各式内存价格全面走扬,尤其NOR Flash从小零件变成抢手货,旺宏(2337)股价翻了好几番。 旺宏因减资作业预计28日重新上市,土洋法人买超集中到华邦电(2344),带动今早股价再创最高20.7元。
发表于: 10:31:42
虽然全球DRAM供应短缺的问题正得到逐步缓解,但供需之间仍存在充足的缺口——至少能够让各芯片制造商继续迎来创纪录的营收总值。
发表于: 09:14:30
有偿征稿 | 2017年能耗过半,年初定的哪些“小目标”没有阵亡? ……
“这比赛确实将我从大学里整天傻玩混日子的状态,引入电路和程序的奇妙世界,从此不能自拔。也因为这比赛,认识了志同道合的一帮朋友,画图刷板采购焊接拼赛道调程序调程序调程序……调到天昏地暗没有出路,就在
第十二届全国大学生“恩智浦”杯智能汽车竞赛全国总决赛将于8月23日至8月26日在常熟理工学院举行,来自全国各地的169个高校的参赛队将汇聚一堂。
哪些队伍将从预赛中脱颖而出?传统强队
第十二届全国大学生“恩智浦”杯智能汽车竞赛全国总决赛将于8月23日至8月26日在常熟理工学院举行,来自全国各地的169个高校的参赛队将汇聚一堂。
哪些队伍将从预赛中脱颖而出?传统强队是否能在决赛
第十二届全国大学生“恩智浦”杯智能汽车竞赛全国总决赛将于8月23日至8月26日在常熟理工学院举行,来自全国各地的169个高校的参赛队将汇聚一堂。
哪些队伍将从预赛中脱颖而出?传统强队是否能在决赛
冠军之争,花落谁家?
摩尔吧作为直播单位将全程为大家直播第12届“恩智浦”杯智能汽车竞赛全国总决赛,记录赛场上每一个拍案叫好的精彩瞬间。
本直播间主拍竞速组。
进入决赛名单:待更新
旗下网站:
与非门科技(北京)有限公司 All Rights Reserved.
京ICP证:070212号
北京市公安局备案编号: 京ICP备:号2007年4月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。Android鍐呭瓨娉勬紡鏌ユ壘锛

我要回帖

更多关于 android studio使用mk 的文章

 

随机推荐