• 使用SDWebImage加载大量图片后造成内存泄露的解决办法


    SDWebImage的知名度就不用说了,github上近10k的star,国内外太多的App使用其进行图片加载。

    但是最近在使用过程中发现,在UITableView中不断加载更多的内容,使用SDWebImage会造成内存占用越来越大,导致memory warning最终terminate,稍微找了下问题原因,发现不少开发者都遇到过这个问题,中文的资料没有搜到该问题的解决办法,为了方便国内其他开发者遇到类似问题不浪费时间,这篇blog把解决方法记录如下:

    首先检查了SDWebImage代码中对于memory warning的处理:

    - (void)clearMemory {
        [self.memCache removeAllObjects];
    }

    其中self.memCache是NSCache类型的,可以看到SDWebImage本身对内存警告执行了操作,但是并没有什么X用。

    用Instruments的allocations分析了一下内存使用情况:

    可以看到内存基本都在decodedImageWithImage:这个方法里被占用了,查看了这个方法的内部实现,感觉还是比较正常的,只好求助google

    最后在github上找到了这条issue:https://github.com/rs/SDWebImage/issues/538

    下面回复很多(看来这个问题很多人都遇到了),甚至SDWebImage的作者本人rs也在下面进行了很多的回复(虽然他的回复并没有什么X用),回复里说到的问题原因和解决办法归纳如下:

    1.rs本人回复的:SDWebImage用到的NSCache会在合适的时候(memory warning)释放内存,很多应用在加载大量图片的时候没有出现这种情况;

    2.这个问题是因为SDWebImage对GIF的支持的代码造成的,去掉相关代码即可;

    3.decodedImageWithImage的实现直接retrun image即可;

    4.https://twitter.com/0xced/status/332252283758845953,这条Twitter也是蛮幽默的,通俗的翻译就是这条Twitter中描述的解决办法拯救了那些因为SDWebImage导致问题的程序员于水火之中。

    挨个试了试上面4中解决方法:

    第一种没什么可说的了,之前分析源码的时候就已经看到,也就是说rs的解决办法没用。

    第二种办法,阅读源码可以发现SDWebImage中对GIF的处理只会针对GIF图片,并不会影响到png或者其他格式的图片,因此这个办法我觉得没用,没有尝试。

    第三种,直接导致内存占用原因由CG raster data变成了ImageIO_PNG_Data,也是没用。

    第四种,最开始我在receive memory warning的时候调用了这段代码

                [[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"];

    发现依然会出现问题,遂尝试了每次加载更多内容的时候都执行一次,终于内存不再持续增加了,也就是说第四种是最终的解决办法,在后续blog我可能会专门分析一下这个问题出现的原因和解决的原理。

    总结如下:

    在使用SDWebImage加载较多图片造成内存警告时,定期调用

     [[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"];

    可解决。

  • 相关阅读:
    C++ Node template typename T
    C++ BST Insert Print,compile via g++ ,the *.cpp asterisk can represent all the files end with cpp
    springmvc 请求数据 全局过滤器
    spring mvc页面跳转和回写
    Conda 换源
    d2l 安装,提示 "error:Microsoft Visual C++ 14.0 or greater is required.Get it with "Microsoft C++ Build Tools""
    Conda 安装配置
    UI卡顿假死问题
    System.NotSupportedException:“该类型的 CollectionView 不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改。”
    List<T>和ObservableCollection<T>的相互转换
  • 原文地址:https://www.cnblogs.com/ziip/p/4664234.html
Copyright © 2020-2023  润新知