求一个存在android 内存泄漏检测的Android app(带源码)~

> AndroidApp定位跟规避内存泄漏办法研究
AndroidApp定位跟规避内存泄漏办法研究
scumajian & &
发布时间: & &
浏览:82 & &
回复:0 & &
悬赏:0.0希赛币
AndroidApp定位和规避内存泄漏办法研究
  本文档包含如下内容:
  l 如何断定App存在内存泄漏
  l 如何定位App的内存泄漏地位
  l 如何避免内存泄漏
2. 名词申明
  App:Application
  VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
  RSS - Resident Set Size 实际应用物理内存(包含共享库占用的内存)
  PSS - Proportional Set Size 实际应用的物理内存(比例分派共享库占用的内存)
  USS - Unique Set Size 过程独自占用的物理内存(不包含共享库占用的内存)
  一般来说内存占用大小有如下规律:VSS &= RSS &= PSS &= USS
3. Android查看内存的对象
DDMS查看体系内存
  在sdk/ android-sdk_eng._linux-x86/tools下,启动ddms,
  ./ddms
  经由过程ddms的sysInfo,如下图,我们可以看到体系内存今朝的分布景象,这是一个饼状图,
  从图中看BaiduReader可能占用了12%,10M阁下的内存。
应用procrank查看过程内存
  procrank 号令可以获合适前体系中各过程的内存应用快照,这里有PSS,USS,VSS,RSS。我们一般调查Uss来反应一个Process的内存应用景象,Uss 的大小代表了只属于本过程正在应用的内存大小,这些内存在此Process被杀掉之后,会被完全的收受接管掉,
  Vss和Rss对查看某一Process自身内存状况没有什么价值,因为他们包含了共享库的内存应用,而往往共享库的资料占用比重是很大的,如许就稀释了对Process自身创建内存波动。
  而Pss是遵守比例将共享内存分别,某一Process对共享内存的占用景象。
  procrank 的代码在 /system/extras/procrank,,在模仿器或者设备上的运行文件位/system/xbin
  在adb shell之后,我们运行procrank下图是Help
  下图是BaiduReader运行下的所有过程的内存应用列表
  从上图我们可以看到,所有的后台守护过程都比基于dalvik的虚拟机过程要小的多,zygote是虚拟机收个过程,由它来负责folk生成其他的虚拟机过程,而刚才PSS中谈到的共享库,其实就是由Zygote加载的,而其他虚拟机过程与Zygote共享这些内存。
应用脚本共同procrank跟踪内存变更
  应用procrank来跟踪某过程的应用哪个景象我们经常借助与脚本。如许就可以查看某一段时候的内存变更。
  如创建一个文件:trackmem.sh    chmod 775 trackmem.sh
  内容如下:
  #!/bin/bash
  adb shell procrank | grep "com.baidu.BaiduReader"
  sleep 1
  运行该脚本:
  ./trackmem.sh
  这个脚本的用处是每1秒钟让体系输出一次BaiduReader的内存应用状况,如下图:
  调查USS的变更,从7M多进步到了9M多,这是因为打开了一个斗劲消费资料的浏览界面,之后的操纵时,络续的反复打开封闭这个界面(Activity),会发明内存只会无意的降落一点,而不会跟从GC的收受接管策略,当Acitivity被封闭之后,相干的资料会一并收受接管,所以我们断定这个Activity很可能存在内存泄漏。
如何断定是否存在内存泄漏
  AndroidApp是基于虚拟机的,其内存经管都是由Dalvik代为经管的,GC的收受接管不是及时的,比如一个Activity被Finish掉之后,其内存的引用对象会鄙人次GC收受接管的时辰,经由过程收受接管算法策画,若是这项目组内存已经属于可收受接管的对象,那么这些垃圾对象会被一并收受接管,所以内存的趋势图可能如下:
  若是我们思疑某一次操纵或者某个界面存在内存泄漏,一般的查找办法是反复这个操纵,或者反复打开封闭这个界面,理论上,每次封闭都邑对应一次大的内存开释,而若是存在内存泄漏的景象,举例如下图,在反复打开封闭Reader的浏览界面的时辰,内存一向在向上爬升,也就是说每次封闭这个Activity的时辰,有些应当开释的内存没有被开释掉
如何定位内存泄漏的地位
  查找内存泄漏一种斗劲土但斗劲彻底的办法就是代码走查,我们可以一行行的解析对象的创建去留等等,但会很耗时候,也斗劲苍茫
  这里给出一种经由过程对象来查找的办法,但此办法只实用于Java层的查找,C/C++是没用的,也就是说只针对与被虚拟机来经管的过程和内存。
  如今向大师引荐Eclipse Memory Analyzer tool(MAT),,可以直接应用RCP版本或者安装其eclipse的插件,下载地址是 。
  Mat的解析文件是hprof文件。 这个文件存放了某Process的内存快照
  如何从手机或者模仿器获得hprof文件呢?
  adb shell
  #ps  (找一下要Kill的过程号)
  # chmod 777 /data/misc
  # kill -10 过程号
  如许会在/data/misc目次下生成一个带当前时候的hprof文件,比如
  heap-dump-tm-pid1059.hprof
  然则这个文件不克不及直接被mat读取,我们须要借助android供给的对象hprof-conv 来把上方的hprof转化为mat可以读取的格局。
  起首将文件pull到当前目次
  adb pull /data/misc/heap-dump-tm-pid1059.hprof ./
  然后借助hprof-conv转换一下格局,此对象在sdk/android-sdk_eng._linux-x86/tools下面.
  ./hprof-conv heap-dump-tm-pid1059.hprof readershot.hprof
  用mat或eclipse打开(若是装mat插件的话) ,选择[Leak Suspects Report],如图 :
  如许就Mat就会为我们主动生成一个泄漏揣摩呈报,如下图,
  从呈报中呈报的三个题目,我们大约可以断定这些处所存在一些题目,
  从上图中Suspect1中,可以看到由class loader加载的HashMap有内存凑集,可能分派了1.6M的内存,所以对比代码中的HashMapEntry,就可以准断定位到有可能存在内存泄漏的处所,经由过程逻辑断定这项目组是否有优化的可能。
  这里趁便介绍一下dalvik.system.PahtClassLoader,这个是Android中Dalvik的体系类和法度类的装载器,所有的.dex都须要经由过程它的装载之后生成我们所须要的对象。
  别的Mat还供给了其他的视图,比如上图可以经由过程类名/Class loadeer来显现各类所占用的堆空间大小,所占内存的比例,对象的数量,经由过程这些参数我们也可以断定哪些对象可能是不太正常的。
  简单介绍一下ShallowHeap和RetainedHeap。
  Shallow size就是对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和。在32位体系上,对象头占用8字节,int占用4字节,不管成员变量(对象或数组)是否引用了其他对象(实例)或者赋值为null它始终占用4字节。
  Retained size是该对象本身的shallow size,加上从该对象能直接或间接接见到对象的shallow size之和。换句话说,retained size是该对象被GC之后所能收受接管到内存的总和。
  借助于Mat堆内存快照的解析,我们根蒂根基可以定位Java层的内存泄漏的题目,Mat是个很强悍的对象,更多的用法请参考。
  而还有一些内存泄漏经由过程Mat是查不出来的,比如native的代码,对C/C++是力所不及的,对于这些题目是本文无法涵盖的,相干可以参考valgrind()
如何避免内存泄漏
  AndroidSDK中有一篇文章专门写了如何避免内存泄漏,这篇文章的中文翻译我贴在了下面。除了下文中提到的Context和View的强引用,还有一些须要重视点:
  1:BraodcastReceiver,ContentObserver,FileObserver在Activity onDeatory或者某类声明周期停止之后必然要unregister掉,不然这个Activity/类会被system强引用,不会被内存收受接管。
  2:不要直接对Activity进行直接引用作为成员变量,若是不得不这么做,请用private WeakReference&Activity& mActivity来做,雷同的,对于Service等其他有本身声明周期的对象来说,直接引用都须要谨慎推敲是否会存在内存泄漏的可能;
  3:很多内存泄漏是因为轮回引用造成的,比如a中包含了b,b包含了c,c又包含a,如许只要一个对象存在其他必然会一向常驻内存,这要从逻辑上来解析是否须要如许的设计。
  下文来自
Avoiding Memory Leaks
  避免内存泄漏
  Android应用法度,至少是在 T-Mobile G1上,是被分派了16M的Heap。对于手机来说,这已经是很多内存了,然则对开辟者而言,却显的很少。尽管你没有筹算用光所有的内存,也应当尽量罕用内存以至于其他应用法度不被杀掉。越多的应用法度被Android保存在内存里,用户在切换法度的时辰就越快。作为我工作的一项目组,我碰到的大项目组 Android应用法度中的内存泄漏题目都是因为雷同的原因:对 Context对峙一个长生命周期的引用。
  在Android里,一个Context被用于很多操纵,然则大项目组是用于加载和接见资料。这就是为什么所有的widget在他们的机关里都接管一个Context的参数。在一个典范的Android应用法度里,你经常用到两种Context,Activity 和Application。开辟者经常把前者传到须要Context的类和办法里。
  @Override
  protected void onCreate(Bundle state) {
    super.onCreate(state);
    TextView label = new TextView(this);
    label.setText("Leaks are bad");
    setContentView(label);
  这就意味views有一个对这个activity的引用,也就是对峙了该Activity里的所有引用,经常是全部view体系和它所有的资料。是以若是你"泄漏"了Context("泄漏"意思是你保存了一个引用,是以阻拦了GC收集它),你就泄漏了很多内存。若是你不重视的话,泄漏全部Activity真的很轻易。
  当屏幕的orientation变更时,默认景象下体系会烧毁当前的activity再创建一个保存本来状况的新activity,这时Android会从资料中从头加载这个application的UI。如今假设你写的一个application里有一个很大的bitmap,你又不想每次转屏都从头加载。最简单的体式格式就是把它保存为一个static变量:
  private static Drawable sB
  @Override
  protected void onCreate(Bundle state) {
    super.onCreate(state);
    TextView label = new TextView(this);
    label.setText("Leaks are bad");
    if (sBackground == null) {
      sBackground = getDrawable(R.drawable.large_bitmap);
    }
    label.setBackgroundDrawable(sBackground);
    setContentView(label);
  这个代码很是快,然则也是很是错误的,它泄漏了屏幕扭转前的activity。当一个 Drawable附到一个view上时,view就被作为一个callback设置到drawable上。在上方一小断代码里,就意味着该drawable有一个对textview的引用,而这个textview又有对这个activity(就是这个context)的引用,而这个activity里有很多对其他对象的引用(取决你的代码)。
  这个例子是一个泄漏Context的最简单的景象,你可以在 Home screen""s source code(办法unbindDrawables())看到当一个activity被烧毁时我们是怎么工作的,我们会设置保存drawable的callback为null。有很多景象可以造成一系列context泄漏,它们会很快地耗光你的内存,这些很是不好。
  有两个简单的办法来避免context相干的内存泄漏。最明显的办法是避免context跨越本身的应用局限。上方的例子注解对外部静态变量的引用同样危险。第二种解决办法是用Application context。这个context会存活在全部application生命周期中,它不依附activity的生命周期。若是你想保存一个须要context的长生命周期的对象,记住应用Application context。你可以经由过程调用 Context.getApplicationContext() 或者Activity.getApplication()来获得它。
  总之,为了避免context相干的内存泄漏,记得下面的步调:
  不要在context-activity里保存长生命周期的引用 (对于activity的引用,应当有和这个activiy雷同的生命周期)
  试着应用Application context来庖代context-activity
  若是你不想把握非静态内部类的生命周期,就要避免在一个activity里应用它,而要用一个静态的内部类,对外部的这个activity有一个弱引用。这种解决办法有一个实例: ViewRoot和它的内部类中有一个对外部类的WeakReference。
  GC对内存泄漏是力所不及的。
  参考材料
  How to avoid memory leak
  How to use Eclipse Memory Analyzer to analyze JVM Memeory
  valgrind
  MAT Wiki
  Understanding Weak References译文
  Java HotSpot VM Options
  Shallow and retained sizes
  JVM Memory Structure
  #q= procrank&t=0
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&安卓应用源码
<font color='#ff-03-15
安卓手机(android)wifi传送文件源码 可以实现一个android手机之间 , 手机和PC 之间 可以通过wifi相互传文件的程序 。亲测可用 :) 程序分为 android手机端的 apk 和 Pc端的 exe 两个 文件 。 程序会自己建立一个热点 ,另一个手机或PC 连接到网络 即可通过...
<font color='#ff-03-15
ImageView控件缩放和旋转图片源码 演示了如何使用ImageView控件缩放和旋转图片,帮助理解用法,并附带实例,对新手实用,学到一些基础的图像操作技巧,比如按比例缩放图片、旋转图片到指定的角度,在一些Android应用中,我们经常见到这些功能。...
很多朋友可能跟我一样,不太喜欢长按电源键来关机,而且有时候长按坏更是没办法关机 , 关机和重启(reboot and shutdown)源码 程序可以简单实现此功能 。 备注:要获取了Root权限才行。...
360手机卫士后台通知listview滑动删除 ,继承listview 重写onTouchEvent(..)方法 ,监听滑动。获得滑动的位置,转化为listview中对应的item的position。在Adapter中对应的list(存放的数据) 中删除对应的数据,更新listview 完成一次删除。...
动态壁纸(Wallpaper)案例源码
这是一款实现了 动态壁纸(Wallpaper)案例源码 ,该源码说明很详细,而且思路又很清晰的,界面设计也还可以,是一个很好的学习动态壁纸的案例,知道大家的研究与学习。 效果图:...
笑话故事android应用源码 采用jsoup抓取网页上的笑话故事(源码)。供新手学习咯。...
android掌上几分钟视频应用源码 具有在线视频播放功能。数据接口使用的是56网的开放平台的。另外还有下载功能以及微博分享哦。...
这次给大家分享的是一个 诗词散文阅读和小说更新的开源 APP 。 服务端是使用源于 Node.js 的 HTML 模板引擎Jade构建的。 爬虫是用py写的。 android是用android studio写的。没找到apk所以无法给大家演示了,感兴趣的可以自己下载试一下,爬虫和服务已经全部...
SMplayer 音乐播放器 是一个来自百度贴吧的音乐播放器项目,歌词显示控件使用自定义控件。只是本地音乐播放器项目,学生作品。UI和功能可能会存在各种bug,介意勿下! 歌词实现思路是:先把每列歌词中的中括号都用Pattern+Matcher提取出来,每行提取到的去掉...
全国计算机等级考试全真模拟考试软件 _一级计算机基础及MS Office应用完全按照《全国计算机等级考试最新考试大纲》研制而成,界面全真模拟、精选习题、详尽解析,适合参加2017年上半年(3月份)考试人员和所有学习计算机基础操作、MS Office及上网的人员使用...
CoordinatorTabLayout是一个自定义组合控件,可快速实现TabLayout与CoordinatorLayout相结合的样式 继承至CoordinatorLayout, 在该组件下面使用了CollapsingToolbarLayout包含TabLayout...
原理其实很简单,就是通过监听ScrollView在Y轴的滑动距离,然后在代码中动态设置头像的位置和大...
利用GridView实现单选功能的demo...
仿探探主页的效果制作,可以左右上下滑动...
本项目拍照只获取自定义的矩形区域图片的一个小例子,不过不知道为什么在红米上测试的时候感觉摄像头跟有一层雾一样,并且画面有拉伸感,这个例子拍出来的图片直接储存到sd卡了,有这方面需求的朋友可以研究一下,项目有中文注释,默认编译版本4.4.2编码GBK...
本例子是一个引导页聚焦引导效果的例子源码,启动引导的时候除了设置的引导区域以外的所有地方都是半透明的黑色,点击第一个引导位置会转跳到第二个引导位置,下面的引导位置以此类推,默认编译版本4.4.2编码GBK...
本项目是一个简单的医院挂号项目源码,实现了病人在安卓手机上登录、注册、挂号、查看医生信息等功能。实现原理是app端与web服务端做交互,然后web服务端再去调用mysql数据库里面的内容,维护mysql数据内容的时候直接在web服务端进行维护本项目暂时没有数据...
本项目是一个静默卸载手机上已经安装的app的小例子,翻了下菜单看了有文件加密、文件解密、报文鉴别、编辑文件、删除文件等功能,加密有des、desede、aes三种算法,因为小编不了解加密解密这一块所以就不妄加评论技术细节了,了解这一块的朋友自己下载研究一...
本项目是一个静默卸载手机上已经安装的app的小例子,传统的安卓应用卸载会直接转跳到系统的应用详情界面点击卸载才能一个个的卸载,本例子卸载应用的时候不需要弹出应用管理界面直接静默卸载手机非内置应用,用户体验良好并且支持选择多个app一起卸载,但是...
本项目是一个可以自动定位和手动选择的天气预报源码,打开app首先会有一个四屏的引导界面,城市定位有自动定位(百度)和手动选择功能手动选择加载时间较长貌似是因为省市信息是在网络获...
安卓源码分类
增值电信业务经营许可证:苏B2-CopyRight &#169;
All Rights reserved.推荐这篇日记的豆列
······
&(1人关注)&>&&>&&>&&>&外卖系统源码带app
外卖系统源码带app
上传大小:43.88MB
最新外卖系统,多店铺运营,支持短信、微信等通知消息,可生成apk和ios.方便手机用户直接订外卖。
综合评分:3.6(52位用户评分)
所需积分:0
下载次数:1150
审核通过送C币
创建者:lirenzuo
创建者:lirenzuo
课程推荐相关知识库
上传者其他资源上传者专辑
行业热门标签
VIP会员动态
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
android服务器底层网络模块的设计方法
所需积分:0
剩余积分:720
您当前C币:0
可兑换下载积分:0
兑换下载分:
兑换失败,您当前C币不够,请先充值C币
消耗C币:0
你当前的下载分为234。
外卖系统源码带app
会员到期时间:
剩余下载次数:
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:

我要回帖

更多关于 android 检查内存泄漏 的文章

 

随机推荐