美文网首页Android实用技术Android开发经验谈Android开发
记使用RxJava保存byte[]到文件,遇到的内存泄漏问题

记使用RxJava保存byte[]到文件,遇到的内存泄漏问题

作者: Jlanglang | 来源:发表于2017-10-02 00:37 被阅读90次

    前言

    最近写一个页面内会多次拍照并保存的需求.连拍多次发现内存泄漏.
    找原因花了不少时间.记录下来.

    问题:

    Paste_Image.png Paste_Image.png

    将byte[]保存为文件.明明已经关闭了流.

    然而一顿连拍后,内存监控却大吃一惊.

    Paste_Image.png

    点小黄车gc也不好使....


    Paste_Image.png

    内存分析:

    Paste_Image.png
    查看内存报告.很明显,byte[]数组泄漏了.
    Paste_Image.png

    找到内存占用很大的byte[]

    Paste_Image.png

    什么?

    Paste_Image.png

    很明显,Rxjava引用了这个数组,并且这个observerable没被回收.

    先从Rxjava入手了.看源码

    Paste_Image.png

    这里保存了byte[]引用.

    那么就是Observable订阅没取消咯.

    什么?不是走了onCompleted()后就会释放吗?

    具体原因:

    使用CompositeSubscription添加了subscribe
      Subscription subscribe = Observable.just(data)
      ``````//具体逻辑省略
      mCompositeSubscription.add(subscribe);
    
    • 因为CompositeSubscription添加了Subscription,onCompleted()不会取消订阅.
      必须通过CompositeSubscription.unsubscribe().然而使用了这个方法后CompositeSubscription就不能再添加订阅了

    解决办法:

    1.使用clear()方法,而不是unsubscribe()
      mCompositeSubscription.clear();
      Subscription subscribe = Observable.just(data)
       ````//省略
    
    2.不使用CompositeSubscription.(不推荐)
    //mCompositeSubscription.add(subscribe);
    

    总结

    • CompositeSubscription.clean(),取消添加的所有订阅,能继续添加订阅
    • CompositeSubscription.unsubscribe(),取消所有订阅,不能继续添加订阅
    • 使用CompositeSubscription添加了订阅后,onCompleted()执行后无法完全解除订阅(ps:其实在CompositeSubscription.add()的时候已经调用了.)
    虽然问题解决很简单.但是找原因还挺麻烦的.
    1.以为bitmap没回收.使用弱引用发现依然没效果.
    2.查到byte保存为文件时出的问题.
    3.查到RxJava转换操作会保存引用.再
    4.分析猜是没取消订阅.
    5.发现确实是CompositeSubscription的问题
    

    希望以上找bug的过程能给各位带来帮助和思路.


    您的喜欢与回复是我最大的动力-_-(ps:还不是为了出名,为了吸粉)

    交流群:493180098,这是个很少吹水,有人解决问题的群.

    相关文章

      网友评论

      本文标题:记使用RxJava保存byte[]到文件,遇到的内存泄漏问题

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