概述
防止内存泄漏
使用Service时,尽量使用IntentService,这样可以避免忘记关闭服务。
避免一个对象被比它生命周期长的对象持有或引用,这样会导致该对象无法被释放,内存泄露。
如对一个Activity Context保持长生命周期的引用,即使这个Activity已经被销毁了,但相关内存无法被释放。对于生命周期长的对象,可以使用ApplicationContext。
非静态内部类的静态实例容易造成内存泄漏,这个静态实例的生命周期超过了类本身:如Activity中的一些特殊Handler等,尽量使用静态类和弱引用来处理。BroadCastReceiver要记得注销处理。
在Activity的onDestroy方法中调用handler.removeCallbacksAndMessages(null),取消所有消息的处理,将所有的Callbacks和Messages全部清除掉。
在查询SQLite数据库时,会返回一个Cursor,当查询完毕后,及时关闭。
线程不再需要继续执行的时候要记得及时关闭。
如在Activity中关联了一个生命周期超过Activity的Thread,在退出Activity时切记结束线程;像HandlerThread的run方法是一个死循环,它不会自己结束,线程的生命周期超过了Activity生命周期,必须手动在Activity的销毁方法中调用thread.getLooper().quit()结束。属性动画导致内存泄露
在Activity中启动了属性动画(ObjectAnimator),但是在销毁的时候,没有调用cancle方法,虽然我们看不到动画了,但是这个动画依然会不断地播放下去,动画引用所在的控件,所在的控件引用Activity,这就造成Activity无法正常释放。谨慎使用static对象
因为static的生命周期过长,和应用的进程保持一致,使用不当很可能导致对象泄漏。
防止OOM
有效节省内存,那就极大降低了OOM发生的概率。后面总结一些节省内存的策略。
不要加载过大的Bitmap对象,采用降低图片质量的方法减少内存消耗。Bitmap对象不用时,即使销毁。
批量加载数据时,不要加载的太多,同时进行缓存设计。
在做一些大内存分配等可疑内存操作时进行trycatch操作,避免不必要的应用闪退。
(可以通过ActivityManager的getMemoryClass()来获取APP被分配的可用内存)注意在ListView/GridView等出现大量重复子组件的视图里面对ConvertView的复用。使用RecyclerView代替ListView/GridView。
避免在onDraw方法里面执行对象的创建.
类似onDraw等频繁调用的方法,一定需要注意避免在这里做创建对象的操作,因为他会迅速增加内存的使用,而且很容易引起频繁的gc,甚至是内存抖动。多次横竖屏切换
多次横竖屏切换,导致activity的生命周期不断销毁创建,次数多了就OOM。
缓存
- 缓存设计
- 为了能够正常清除与应用相关的缓存,需将缓存文件存放在getCacheDir()或者getExternalCacheDir()路径下。
- 为了安全起见,缓存的文件名可以使用MD5加密,对某些文件内容也可以进行加密。
- 有两种方式判断是否需要更新本地的缓存文件,一是根据文件的修改时间,一是根据文件的版本号,两者都需要服务器端把这些数据传递给APP端。
LruCache(Least Recently Used Cache)
这其实就是一个LinkedHashMap,任意时刻,当一个值被访问时,它就会被移动到队列的开始位置,所以这也是为什么要用LinkedHashMap的原因,因为要频繁的做移动操作,为了提高性能,所以要用LinkedHashMap。当cache满了时,此时再向cache里面添加一个值,那么,在队列最后的值就会从队列里面移除,这个值就有可能被GC回收掉。
这个LruCache在android.util包下,是API level 12引入的,对于API level 12之前的系统可以使用support v4包中的LruCache。
如果我们想主动释放内存,也是可以的,我们可以重写entryRemoved(Boolean, K, V, V)方法。
这个类是线程安全的,在多线程下面使用这个类,不会存在问题。
synchronized (cache) {
if (cache.get(key) == null) {
cache.put(key, value);
}}
做好内存优化是一项长期的工作, 需要在很多地方注意,欢迎大家提出平时遇到的内存相关问题或者优化策略,我将持续做好总结。
常用工具、
1.LeakCanary 检测内存泄漏
LeakCanary作为一个简单粗暴的工具,用法也相当简单
- 首先,在build.gradle中引入LeakCanary。
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
}
- 然后,需要在你的application中启动它,LeakCanary是测试整个app的内存泄露情况。
import android.app.Application;
import com.squareup.leakcanary.LeakCanary;
public class MyApplication extends Application {
public static RefWatcher getRefWatcher(Context context) {
MyApplication application = (MyApplication) context.getApplicationContext();
return application.refWatcher;
}
private RefWatcher refWatcher;
@Override public void onCreate() {
super.onCreate();
refWatcher = LeakCanary.install(this);
}
}
更多使用说明
2.BlockCanary 检测卡顿
BlockCanary是一个Android平台的一个非侵入式的性能监控组件,应用只需要实现一个抽象类,提供一些该组件需要的上下文环境,就可以在平时使用应用的时候检测主线程上的各种卡慢问题,并通过组件提供的各种信息分析出原因并进行修复。
具体使用参考文章以及原理分析。
文章部分内容摘自网络,如有不妥请联系本人!
最后
以上就是重要香水为你收集整理的Android性能优化--防止内存泄漏的全部内容,希望文章能够帮你解决Android性能优化--防止内存泄漏所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复