文档章节

开发者使用的内存清理、Pss监控工具

Cundong
 Cundong
发布于 2015/04/10 14:46
字数 1547
阅读 2463
收藏 30

MemoryMonitor

一个给开发者使用的Android App内存清理、监控工具,可以获取当前手机的内存使用比率,可用内存大小,检查一个APP是否存在内存泄漏。

并且整理了一些优化内存的方式。

0.GitHub地址

1.内存清理

类似360卫士的 加速球,获取系统已用内存比率、可用内存大小,一键清理。

可以用于测试自己开发的Activity、Fragment健壮性,模拟Activity、Fragment被回收的场景,测试自己的程序是否完好的保存、恢复当前场景。

比如:打开你开发的某个Activity、Fragment,切到后台,清理一次内存,在将其切回前台后,看会不会出现空指针异常,以及程序状态是否被恢复。

2.内存监控

Android系统中的内存和Linux系统一样,存在着大量的共享内存。每个APP占内存会有私有和公共的两部分,我们可以通过App的Pss值,可以获取到这两部分内存。

Pss(Proportional Set Size):实际使用的物理内存,即:自身应用占有的内存+共享内存中比例分配给这个应用的内存。

通过改程序,每隔1秒,获取一次被监控App的Total Pss值。

使用某个功能(可能会导致OOM的那些都要试试),查看Pss是否飙升,或者使用过许久都没有降低。

如果使用后飙升并且长时间都降不下来,那就说明肯定会导致OOM(对象使用过之后还被引用着未释放),如果使用之后Total Pss飙升,但是使用过之后能降下来,也可能会导致OOM,我们还是需要去一点一点排查是什么原因导致的。

如果使用后飙升并且长时间都降不下来,我们就需要使用MAT来进一步分析问题所在。

3.内存优化

Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般比较小(最低端的设备16M,后来出的设备变成了24M,48M等等),因此我们所能利用的内存空间是有限的。如果我们使用内存占用超过了一定的限额后就会出现OutOfMemory的错误。

可能会导致内存溢出的情况有以下几种:

1)对静态变量的错误使用

如果一个变量为static变量,它就属于整个类,而不是类的具体实例,所以static变量的生命周期是特别的长,如果static变量引用了一些资源耗费过多的实例,例如Context,就有内存溢出的危险。

Google开发者博客,给出了一个例子:http://android-developers.blogspot.jp/2009/01/avoiding-memory-leaks.html 专门介绍长时间的引用Context导致内存溢出的情况。

这种情况:

静态的sBackground变量,虽然没有显式的持有Context的引用,但是: 当我们执行view.setBackgroundDrawable(Drawable drawable);之后。 Drawable会将View设置为一个回调(通过setCallback()方法),所以就会存在这么一个隐式的引用链:Drawable持有View,View持有Context sBackground是静态的,生命周期特别的长,就会导致了Context的溢出。

解决办法: 1.不用activity的context 而是用Application的Context; 2.在onDestroy()方法中,解除Activity与Drawable的绑定关系,从而去除Drawable对Activity的引用,使Context能够被回收;

2)长周期内部类、匿名内部类长时间持有外部类引用导致相关资源无法释放

长周期内部类、匿名内部类,如Handler,Thread,AsyncTask等。

HandlerOutOfMemoryActivity所示的是Handler引发的内存溢出。

ThreadOutOfMemoryActivity所示的是Thread引发的内存溢出。

AsyncTaskOutOfMemoryActivity所示的时AsyncTask引发的内存溢出。

3)Bitmap导致的内存溢出

一般是因为尝试加载过大的图片到内存,或者是内存中已经存在的过多的图片,从而导致内存溢出。

4)数据库Cursor未关闭

正常情况下,如果查询得到的数据量较小时不会有内存问题,而且虚拟机能够保证Cusor最终会被释放掉,如果Cursor的数据量特表大,特别是如果里面有Blob信息时,应该保证Cursor占用的内存被及时的释放掉,而不是等待GC来处理。

5)单例模式引用Context导致的内存泄露

如果在某个Activity中使用 Singleton instance = Singleton.getInstance(this); 就会造成该Activity一直被 Singleton 引用着,不能释放。这时候,正确的做法是使用 getApplicationContext() 来替代 Activity的Context ,这样就能避免内存泄露。

6)代码中一些细节

  • 尽量使用9path
  • Adapter要使用convertView
  • 各种监听,广播等,注册的同时要记得取消注册
  • 使用完对象要及时销毁,能使用局部变量的不要使用全局变量,功能用完成后要去掉对他的引用
  • 切勿在循环调用的地方去产生对象,比如在getview()里new OnClicklistener(),这样的话,拖动的时候会new大量的对象出来。
  • 使用Android推荐的数据结构,比如HashMap替换为SparseArray,避免使用枚举类型(在Android平台,枚举类型的内存消耗是Static常量的的2倍)
  • 使用lint工具优化工程
  • 字符串拼接使用StringBuilder或者StringBuffer
  • 尽量使用静态匿名内部类,如果需要对外部类的引用,使用弱引用
  • for循环的使用 用 final int size = array.length; for(int i = 0; i< size;i++) 来替代: for(int i =0;i < array.length;i++)

最后。

我整理了一些开发中可能会导致内存溢出的情况,放在com.cundong.memory.wrong中,并且给出了优化方法,放在com.cundong.memory.right中。

4.截图

截屏

© 著作权归作者所有

Cundong
粉丝 185
博文 28
码字总数 30973
作品 0
海淀
私信 提问
加载中

评论(1)

dongcfang
dongcfang
2
Linux监控工具介绍系列——smem

smem工具介绍 smem是Linux系统上的一款可以生成多种内存耗用报告的命令行工具。与现有工具不一样的是smem可以报告实际使用的物理内存(PSS),这是一种更有意义的指标。可以衡量虚拟内存系统...

mrliuze
2016/01/27
40
0
跨平台网络服务器框架--PSS

目前代码更新更新在github上,就不维护多个服务器SVN了。 请到github上自取 ,地址为 https://github.com/freeeyes/PSS PSS 是易于开发,基于插件的,跨平台网络服务器框架,支持开发者使用插...

自由的眼
2014/11/17
2.7K
0
使用 pss 搜索你的代码

搜索代码库是开发者每天都要做的事情。从修改 bug 到学习新代码,或者查看如何调用某个 API,能快速在代码库中导航的能力都是一大助力。幸运的是,我们有专门的工具来搜索代码。pss[1] 就是其...

linux-tao
2018/01/11
17
0
手机APP性能测试工具iTest3.0

小伙伴们,你会经常为手机卡、死机、或者自动关机而恼火么?想知道为什么手机的内存总不够用么?想知道为什么手机的流量没怎么用就超了么?想知道到底什么应用耗尽了手机的电量么? 给你推荐...

源远流长14
2014/11/06
1K
1
Linux用户态进程的内存管理

上一篇我们了解了内存在内核态是如何管理的,本篇文章我们一起来看下内存在用户态的使用情况,如果上一篇文章说是内核驱动工程师经常面对的内存管理问题,那本篇就是应用工程师常面对的问题。...

p23onzq
2018/04/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

一套基于SpringBoot+Vue+Shiro 前后端分离 开发的代码生成器

一、前言 最近花了一个月时间完成了一套基于Spring Boot+Vue+Shiro前后端分离的代码生成器,目前项目代码已基本完成 止步传统CRUD,进阶代码优化: 该项目可根据数据库字段动态生成 controll...

郑清
28分钟前
2
0
javascript-十六进制随机颜色

<script> // 编写一个函数,获得一个十六进制的随机颜色的字符串(如#20CD4F) // function randomColor(){ // var r = random(0,255).toString(16); // var g = random(0,255).toString(16......

ACKo
30分钟前
2
0
springBoot +mybatis 出现sql 语句在数据库可以查询到,但是赋值到实体类上就没有的情况?

1.不要老是反复查看自己是否写错了,为啥有的能出来有的出不来? 可以查看配置文件中是否配置全: 如果在application.yml 文件中是如下配置: mybatis: mapper-locations: classpath:mapp...

kuchawyz
43分钟前
2
0
正则表达式

一、RegExp对象 进行验证和查找的API 1、创建对象: (1)用/创建(直接量):var reg=/正则/ig,表达式固定不变时使用 (2)用new创建:var reg=new RegExp(‘正则’,‘ig’),表达式需要...

wytao1995
43分钟前
2
0
实战限流(guava的RateLimiter)

关于限流 常用的限流算法有漏桶算法和令牌桶算法,guava的RateLimiter使用的是令牌桶算法,也就是以固定的频率向桶中放入令牌,例如一秒钟10枚令牌,实际业务在每次响应请求之前都从桶中获取...

程序员欣宸
44分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部