美文网首页
App内存和性能优化

App内存和性能优化

作者: Neo_duan | 来源:发表于2018-01-13 12:11 被阅读38次

    ANR(Application Not Responding)

    5s程序无响应,主线程做耗时操作引起,也就是主线程被阻塞。
    
    发生在主线程中的有:
    Activity、Service、BroadcastReceiver的onReceive回调
    主线程中new Handler();
    view.post(Runnable)
    
    解决方式:
    使用AsyncTask处理耗时操作
    使用Thread和HanlderThread提高优先级
    Activity的生命周期回调中尽量不要做耗时操作
    

    app申请的内存

    每个app分配的最大内存限制,随不同设备而不同
    
    
    切换应用时后台app清理机制:
    LRU Cache机制:最近使用的排在最前面,最少可能的被清理
    清理内存回调onTrimMemory方法
    

    Java中的引用方式

    强引用:对象强引用,当内存不足,虚拟机宁愿抛出OOM,也不会随意回收强引用
    软引用(SoftReference):当内存不足时候,垃圾回收器才回收
    弱引用(WeakReference):当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象
    虚引用(PhantomReference):如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收
    ps:被软引用关联的对象只有在内存不足时才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收...
    

    ** 优化方法**

    数据结构的优化

    • 字符串的拼接用StringBuilder(替换频繁的String字符拼接等)
      字符串通过+的方式进行拼接会产生中间字符串内存块,这些都是没有用的。

    • ArryMap、SpareseArray替换HashMap
      因为ArryMap、SpareseArray内存占用少,且效率更高

    • 内存抖动
      一时间创建很多对象

    • Service使用完尽量停止

    对象复用

    1、复用系统自带资源
    2.ListView相关复用
    3.避免在onDraw中创建对象
    

    避免内存泄露

    代码问题导致这块内存,虽然停止使用,但依然
    被其他对象引用这,使得GC没发对它回收
    

    1.避免Activity泄露,用弱引用
    2.引用Context时,能用Application尽量用Application

    • Context 泄漏, 主要为Activity 传递泄漏, context 未使用applciationConext 在单例创建时。
      • Handler 泄漏 , handler中持有view ,context 等做耗时操作。
      • Cursor 泄漏 , cursor未关闭
      • register 未 unregister
      • Bitmap
      • adapter 未使用convertView
      • WebView内存泄露
      • 不良代码等
    WebView内存泄露解决方式:
        https://stackoverflow.com/questions/3130654/memory-leak-in-webview
        Android系统的一个bug:通过XML布局创建WebView时,活动作为WebView的上下文而不是应用程序上下文传递。 完成活动后,WebView仍然保持对活动的引用,因此活动不会从内存中移除。 必须使用new创建:
        WebView webView = new WebView(getApplicationContext());
        
        webView销毁:
        ```
        @Override
        protected void onDestroy() {
        super.onDestroy();
        if (null != mWebView) {
            //解除webView与父控件的依附关系
            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.removeAllViews();
            mWebView.setTag(null);
            mWebView.clearHistory();
            mWebView.loadUrl("about:blank") ;
            mWebView.setVisibility(View.GONE);
            mWebView.destroy();
            mWebView = null;
            }
        }
        ```
    
    资源使用完未关闭(BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap)
    
    写完程序对程序进行Review,或者用代码检测工具检查,运行时候使用LeakCanary检查是否有内存泄露。内存紧张时释放一些图片内存等
    如查询数据库的操作,使用到Cursor,也要对Cursor对象及时关闭
    ndroid程序里面存在很多需要register与unregister的监听器,手动add的listener,需要记得及时remove这个listener。
    

    强引用、软引用、弱引用

    优化OOM

    1.注意临时Bitmap对象的及时回收
    2.加载Bitmap:缩放比例、解码格式、局部加载
    

    性能优化

    卡顿原理:
        60fps->16ms,如果16毫秒在60帧以下,就会卡顿
    
    解决方式:
        不要在主线程中做轻微的耗时操作
        同一时间动画执行次数过多,导致CPU或GPU负载过重,要避免
        列表Adapter的复用
        布局优化:
            去除XML布局中不必要的bg设置
            减小View的层级,使用ViewStub
            避免嵌套过多无用布局,同样的层级LinearLayout优于RelativeLayout.
            merge标签的使用
    
    冷启动:
        在启动应用前,系统中没有该应用的任何进程信息
        
        缩短冷启动时间:
        减少onCreate方法的工作量,使用懒加载加载第三方SDK
        
    热启动:
        退出应用后,重启启动应用系统中有该应用的任何进程信息
        
    [启动优化](http://www.jianshu.com/p/f5514b1a826c):
        Splash添加主题
        异步初始化第三方组件(使用IntentService开启后台线程初始化)
    

    Bitmap

    LRU(LruCache)算法:清除最近最少使用的Bitmap, put进去的时候有个putCount的计数器,可以判断putCount最小的就是最少使用的

    计算inSampleSize

    缩略图

    三级缓存:先查内存--->SD卡--->网络请求

    其他优化

    不要使用静态变量存储数据
    
    Shareprefrence:
        不能跨进程同步
        不能存储大数据,因为读写値会阻塞主线程,并且会产生大量临时对象,频繁GC导致内存抖动等等
    

    APK瘦身

    使用一套资源,且图片使用tinypng有损压缩
    启动页使用jpg 720小图
    webp图片使用
    开启混淆代码
    通过AS工具移除无用资源
    删除无用语言资源
    so包只使用armable目标(微信等大厂app都是这样)
    避免重复库的使用,比如使用了两个图片加载库:Glide和Picasso
    如果raw文件夹下有音频文件,尽量不要使用无损的音频格式,比如wav。可以考虑相比于mp3同等质量但文件更小的opus音频格式
    多用代码实现UI,shape等
    

    电量优化

    及时停止定位
    谨慎使用WakeLock
    

    相关文章

      网友评论

          本文标题:App内存和性能优化

          本文链接:https://www.haomeiwen.com/subject/liqvixtx.html