Android内存泄漏相关
来源:互联网 发布:诅咒淘宝店网址 编辑:程序博客网 时间:2024/06/11 05:18
我打算分两部分来进行说明。第一部分介绍下Android内存泄漏的几种可能,第二部分介绍遇到内存泄漏情况如何进行排查。
一直在说内存泄漏,包括实际项目中或者面试的时候,到底内存泄漏会引起什么呢?
首先就是程序运行越来越卡,程序响应慢甚至无响应。
第二就是当我的程序切到后台的时候回经常性被杀死,因为我们App占用内存过多,会极大可能地被干掉。最严重的就是直接OutOfMemory。
内存泄漏的几种场景
Bitmap的使用
1.图片Size
在使用Bitmap的时候,我们直接从美工那拿到切好的图直接使用,很容易造成内存泄漏。所以我们就必须对Bitmap进行处理,尽量从源头上减少内存的开销。特别是要展示一些缩略图或者对图片质量要求不怎么高的时候,就更应该进行设置。还记得大三暑假的时候参加的一个比赛,当时做的Android项目,在做引导界面的时候,直接使用美工提供的高清无码大图,结果直接滑到第三张的时候直接OOM,当时还很郁闷,找不到原因。
我们可以使用BItmapFactory.Options设置inSampleSize。该参数可以设置显示图的宽高分别为原始图片大小的几分之一。
相关代码如下:
BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options();
bitmapFactoryOptions.inJustDecodeBounds = true;
bitmapFactoryOptions.inSampleSize = 3;
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(sourceBitmap,bitmapFactoryOptions);`
2.图片像素
除了图片的大小外,图片的像素也对内存的消耗有影响:
* ALPHA_8:每个像素占用1byte内存
* ARGB_4444:每个像素占用2byte内存
* ARGB_8888:每个像素占用4byte内存(默认)
* RGB_565:每个像素占用2byte内存
所以如果需求对图片的质量要求不是特别高就可以改下默认值,从而减少开销。
3.图片回收
在图片使用完之后,我们需要对图片进行回收,而不是等系统进行回收。
if(null != bitmap && !bitmap.isRecycled()){
bitmap.recyle();
bitmap = null;
System.gc();(只是建议进行垃圾回收,实际会不会回收无法预知)
}
以上步骤都做了,还是会出现异常的话,我们对使用Bitmap的地方进行OutOfMemory异常捕获,从而进行其他的处理,比如返回一张低分辨率的默认的图片。
对象引用方式不当
对象的引用方式分别有几下几种:
1. 强引用(StrongReference)
2. 软引用(SoftReference)
3. 弱引用(WeakReference)
4. 虚引用(PhantomReference)
下面来介绍下几种引用的区别。
强引用:Object obj = new Object();这个就是强引用,JVM哪怕发生OOM错误也不会回收该对象。
软引用:当内存不够使用时才回收。
弱引用:不管内存是否够用都会回收。
虚引用:和没有任何引用一样,随时都可能被回收。
浮点数的使用过多
使用浮点数会降低效率,增大开销。所以应避免大量浮点数的使用。
ListView使用不当
使用ListView的时候一定要注意是否存在内存泄漏,特别是对于Item条目过多的时候。
具体可以参考我上一篇博客:https://rainyandsunny.github.io/2016/11/03/ListView%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/
Cursor回收
一般情况下我们都会对cursor进行回收,使用完直接关闭,这是个好习惯。
不管我们是做后台或者是做Android开发,这一点大家都很熟悉。但是在使用CursorAdapter的时候就不能关闭啊,关闭了拿不到数据。这就要求我们在ListView所在的Activity的onDestory()中对cursor进行关闭。
类似的还有:广播一定要unregisterReceiver。I/O流等都要记得使用完及时关闭。
Context
尽量使用ApplicationContext而不是Activity,因为引用的实例的生命周期很有可能超出Activity的生命周期,从而造成Activity无法回收,导致内存泄漏。
UI方面
1. 在XML中写布局的时候,都很爽,闭着眼睛都能写,一点码农的感觉,记着我们是工程师,改变世界的那种。但是对写出来的UI一定要记得进行检查,看布局是否合理,是否存在多余节点。幸好Google给我们开发者提供了一款工具用来检查UI视图层级:hierarchyviewer,在SDK tools目录下,至于工具的使用就不介绍了,总之大家一定要有这个意识,写一部分就检查一部分,不要到最后越积越多,哭都来不及。一定要记得!!!!
2. ViewStub标签的使用
我记得Android高级编程中是这么介绍的,懒加载。就是在使用的时候再进行设置,显式地调用inflater或者置为可见的时候才会被填充。
3. merge标签
当含有merge标签的布局被添加到另一个布局文件的时候,该merge标签会被删除,直接将子view进行添加。
4. include标签
一个app里面肯定会有相同的布局,特别是在多人合作的时候,不要你写一个,我写一个。写一份,然后include到需要的父布局中即可。
其他小的Tips
1. View中设置缓存属性.setDrawingCache为true。
2. Android提供给我们的两个工具procstats,meminfo。他们一个侧重于后台的内存使用,另一个是运行时的内存使用。
使用方法:adb shell dumpsys procstats --hours 3(数字自己指定)
adb shell dumpsys meminfo
3. 循环中条件中尽量不要进行相关计算,比如:
for(int i=0;i<arr.lenth;i++){}
类似于这种的,用个变量保存没多大坏处。
4. 我感觉自己有强迫症,老是调用别人的东西就感觉不爽,就喜欢自己实现。但是有些东西,java本身给我们提供了的,就不要自己用java语言再去实现了,因为这样会降低效率,java自己的实现本身有优化。这一点上特别是java对String的处理上。Formatter,DateFormat,TextUtils,MemoryFile等等。这不是拿来主义,我们的目的是提高效率,降低内存的使用。如果有兴趣可以看看别人的实现。
下篇简单讲讲怎么样查找内存泄漏。- android内存泄漏相关
- Android 内存泄漏相关
- Android内存泄漏相关
- Android内存泄漏相关1
- GitHub相关android内存泄漏
- 内存泄漏相关问题
- 内存泄漏相关问题
- android 和java 内存泄漏检测相关问题
- android--内存泄漏的原因及相关分析
- 分享一个Android内存泄漏相关的自动测试脚本
- 内存泄漏的相关文档
- 安卓内存泄漏相关
- 【内存泄漏】Android内存泄漏---单例内存泄漏
- 【内存泄漏】Android内存泄漏---Handler
- Android 内存泄漏调试
- Android 内存泄漏调试
- Android 内存泄漏调试
- Android 内存泄漏调试
- 编程之路
- 二叉树的表示
- 使用JSON.parse()转化成json对象需要注意的地方
- Hihocoder 数组重排
- Java for Web学习笔记(三一):JSTL(7)SQL Tag
- Android内存泄漏相关
- 自定义下拉刷新和上拉加载ListView
- Python实现快速排序
- js中三个容易混淆的东东
- 动态加载Fragment的坑
- poj2449 Remmarguts' Date-k短路+A*(待解决)
- Android单例模式怎么写比较好?
- Docker之Cgroup与接口的使用(二)子系统详解
- 合并k个升序链表(非递归)