我是靠谱客的博主 重要香水,最近开发中收集的这篇文章主要介绍Android性能优化--防止内存泄漏,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

防止内存泄漏

  1. 使用Service时,尽量使用IntentService,这样可以避免忘记关闭服务。

  2. 避免一个对象被比它生命周期长的对象持有或引用,这样会导致该对象无法被释放,内存泄露。
    如对一个Activity Context保持长生命周期的引用,即使这个Activity已经被销毁了,但相关内存无法被释放。对于生命周期长的对象,可以使用ApplicationContext。
    非静态内部类的静态实例容易造成内存泄漏,这个静态实例的生命周期超过了类本身:如Activity中的一些特殊Handler等,尽量使用静态类和弱引用来处理。

  3. BroadCastReceiver要记得注销处理。

  4. 在Activity的onDestroy方法中调用handler.removeCallbacksAndMessages(null),取消所有消息的处理,将所有的Callbacks和Messages全部清除掉。

  5. 在查询SQLite数据库时,会返回一个Cursor,当查询完毕后,及时关闭。

  6. 线程不再需要继续执行的时候要记得及时关闭。
    如在Activity中关联了一个生命周期超过Activity的Thread,在退出Activity时切记结束线程;像HandlerThread的run方法是一个死循环,它不会自己结束,线程的生命周期超过了Activity生命周期,必须手动在Activity的销毁方法中调用thread.getLooper().quit()结束。

  7. 属性动画导致内存泄露
    在Activity中启动了属性动画(ObjectAnimator),但是在销毁的时候,没有调用cancle方法,虽然我们看不到动画了,但是这个动画依然会不断地播放下去,动画引用所在的控件,所在的控件引用Activity,这就造成Activity无法正常释放。

  8. 谨慎使用static对象
    因为static的生命周期过长,和应用的进程保持一致,使用不当很可能导致对象泄漏。

防止OOM

  1. 有效节省内存,那就极大降低了OOM发生的概率。后面总结一些节省内存的策略。

  2. 不要加载过大的Bitmap对象,采用降低图片质量的方法减少内存消耗。Bitmap对象不用时,即使销毁。

  3. 批量加载数据时,不要加载的太多,同时进行缓存设计。

  4. 在做一些大内存分配等可疑内存操作时进行trycatch操作,避免不必要的应用闪退。
    (可以通过ActivityManager的getMemoryClass()来获取APP被分配的可用内存)

  5. 注意在ListView/GridView等出现大量重复子组件的视图里面对ConvertView的复用。使用RecyclerView代替ListView/GridView。

  6. 避免在onDraw方法里面执行对象的创建.
    类似onDraw等频繁调用的方法,一定需要注意避免在这里做创建对象的操作,因为他会迅速增加内存的使用,而且很容易引起频繁的gc,甚至是内存抖动。

  7. 多次横竖屏切换
    多次横竖屏切换,导致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性能优化--防止内存泄漏所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部