概论
很多时候,写代码往往是兴之所至。如行云流水般,想到哪,便可以写到哪,这是多么的让人心旷神怡。然而大多数随兴所至的代码往往缺乏必要的思 考,从而导致一些不必要的内存浪费;这些泄漏累积之下,往往会造成让人头疼的后果,付出难以想象的代价;所以,写代码要学会思考。
思考
android开发中,一部手机允许我们使用的内存空间屈指可数,标准的内存最大容量预计为16M左右,伴随着手机的发展,可能这个内存会扩展为20多 M,甚 至40多M,对于一个需要展示若干多媒体或者图片的App来说,都是杯水车薪;所以,内存的使用需要我们运筹帷幄,把握在自己手里。
1、 新建变量,我们需要思考
1)该对象是否必须创建?
2)该对象是否需要重复创建?
3)该对象是否复用已经存在的对象?
对于以上的三个问题,我们可以Handler来作为示例,Handler有两个方法,sendEmptyMessage和obtainMessage。当我们需要发送一个通知时,可能 我们压根就不需要发送数据,只是作为一个通知使用,那么此时我们可能会习惯性的
Message msg = new Message();
msg.what = 0;
handler.sendMessage(msg);
然而,sendMessage在一个项目中,我们需要调用太多次,需要新建太多Message对象,所以我们可以从系统池中取出复用的对象
Message msg = handler.obtainMessage();
msg.what = 0;
handler.sendMessage(msg);
通过以上步骤,在整个项目中,我们只需要创建一个Message对象即可,剩下的都可以复用之前的对象。对于只作为通知之用,而无需传递数据的情况
handler.sendEmptyMessage(0);
以上一句便足够了。
2、 UI对象,及时释放了吗?
1)什么对象需要及时释放内存?
2)这些对象如何释放内存?
在开发中,实现功能所需要的新建变量所占的内存只是很小的一块;打开应用时,往往看到的是花花绿绿的视图,这些视图加载的背景图片,填充着资源 图片,或者占用着其他资源,这些图片资源的渲染所占用的内存相比于功能对象要多的多,然而,GC回收的资源有时候并不及时,所以需要在不显示的时 候将占用的资源释放掉。释放方式就是1)将背景或者资源置空 2)将控件置空,以ImageView为例
ImageView v;
if(v != null) {
v.setImageDrawable(null);
v = null;
}
3、 Activity/Fragment页面,在销毁时,请不要保持引用!
在开发中,很多人喜欢通过保持Activity引用的方式来实现完全退出吧,一个Activity或Framgnet所占的内存往往占有相当的比重,如果在Activity退出的 时候依旧保持该页面的引用,那么该页面所占的内存便不能够及时有效的回收掉,几个页面下去,嗯,你懂的!
4、不要在重复的逻辑中,建立对象!
在for、while以及遍历等重复的操作中,尽量尽量不要新建对象,除非特别有必要。 特别是在数据量比较大的情况下,加入重复的对象添加其一是需要消 耗大量的内存,其二这些耗费的内存不受我们掌控,不能及时释放掉,会造成很大的隐患。
5、占用内存比较大的变量,在不使用的时候顺便关闭或释放掉,如cursor/db等
在开发中,使用数据库保存一些必要的数据是经常需要的,然而这些操作的cursor或者db等本身保持有不等量的数据或本身就占用大量的资源,在我们执 行完响应的操作后,最好顺手关闭掉,这会使我们的应用做出相应的回馈。
6、良好的控制线程对象
在开发中,数据的请求,文件的传输等都是需要用到线程的,无论是Thread也好,AsyncTask也罢,这些对象本身因为涉及的操作,占据着不小的内存消 耗,所以在执行完或者得到请求的数据后及时的关闭掉,会使得你的应用负担大大的减少。当然网络请求还是建议使用框架来实现,推荐Google原生的 Volley。
7、请注意控制xml界面的层次
在开发中,逻辑的实现需要占据一部分内存空间,视图界面的渲染也要占据一部分的内存,而且涉及到界面的更新,往往需要反复强制渲染,这就使得UI 的内存占用放大了多倍,所以在布局的时候一定要控制xml界面的布局层次,过深的层次布局使得渲染的代价呈指数上升。分析下各布局的设计问题,LinearLayout与FrameLayout属于简单高效的ViewGroup,所以简单布局建议使用LinearLayout;RelativeLayout本身的功能比较复杂,所以如果你需要的是嵌套布局来实现一些效果,那么建议使用RelativeLayout实现。
8、 控制Bitmap的像素
Bitmap占用内存的计算公式: width x height x pixel。在Bitmap的宽度与高度不可改变的情况下,有效的改变图片显示的像素可以大幅度缩减图片所占 的内存空间。这就是看着不大的图片,显示之后会OOM的原因之一,内存相比于原图会瞬间方大几十倍。
9、 图片的加载与释放
在开发中,最占内存空间的资源便是bitmap - 图片,这是众所周知的;图片的内存占用很难控制,包括图片的压缩与释放的时机等。在Java意义上的优 化已经不能满足内存的优化需要,这就是即使添加二级缓存,即使想尽办法去避免还是会产生OOM的原因。所以第九条的优化策略,不是给你们推荐什么 压缩方法与释放,因为这并不能解决问题。真正的解决OOM,最好还是从底层C的层次来使用解决策略,今年五月份Facebook开源的Fresco框架有力的解 决了OOM的问题,该框架从C的层面来解决OOM,解决的很彻底。建议xml的本地图片显示也从Fresco框架来加载,保证彻底解决问题。
还有一篇关于优化的博客,写的挺不错,地址:http://blog.csdn.net/hknock/article/details/47322005
附加:
1、请检查美工给你的图片,是否满足显示要求即可,如果给的图片过大,请自行压缩到符合显示条件即可,如果返回按钮图标,一般44x44就够了
2、带图片的组件,如果该页面需要销毁了,那么释放了吧,通过设置背景或资源为空来实现,这样可以省下大笔的空间
3、后台返回的图片显示,让他们在满足清晰度的前提下,尽可能的压缩吧,不只是内存,主要是大小,因为bitmap的内存衡量与大小息息相关啊
4、对于使用到图片的地方,尽可能保持统一管理吧,在Application新建一个专门用于保持图片的缓存或队列吧,这样不会有任何遗漏内存的地方
5、如果该页面不需要显示了,请释放掉该页面的所有内存,千万不要保持该页面的引用,否则一切都是杯水车薪
6、你的webview,如果用完了,千万记得释放所占的空间,因为真的很大很大,你可用destroy来实现
7、如果你是用的类似主菜单样式,记得保持数据,不要保持引用,主菜单的资源往往是资源占用的大头,保持数据吧,不要犹豫
相信从以上几条进行控制后,基本可以完全避免OOM的问题,可以给你一个流畅的应用程序,还你一个好心情!!!如果该文章帮助到了你,还请动手给个赞!
共同学习,写下你的评论
评论加载中...
作者其他优质文章