Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

High memory use #1544

Closed
CavalcanteLeo opened this issue Apr 30, 2016 · 38 comments
Closed

High memory use #1544

CavalcanteLeo opened this issue Apr 30, 2016 · 38 comments
Milestone

Comments

@CavalcanteLeo
Copy link

CavalcanteLeo commented Apr 30, 2016

SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadImageWithURL:post.imageURL options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) 
{
    // float progress = (float)receivedSize/expectedSize;
    // [cell.imageViewFoto updateProgress:progress];
}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
    if (image) {
        [cell.imageViewFoto setupImageView:post indexPath:indexPath isGrid:NO  image:image];
    }
}];

captura de tela 2016-04-30 as 15 34 24

@mythodeia
Copy link
Contributor

whats the size of the image you are trying to download?

@CavalcanteLeo
Copy link
Author

CavalcanteLeo commented Apr 30, 2016

about 500kb each...
showing in a collectionview, about 18 images at same time...
The problem occurs when i scroll the collectionview, and request more and more and more images...

Maybe i have to disable the memory cache and only store in disk.. but i have no idea how to deal with it

2016-04-30 16 16 21

@mythodeia
Copy link
Contributor

did you try setting these two:

[[SDImageCache sharedImageCache] setShouldDecompressImages:NO];
[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];

by the way, whats the highest resolution of those images?

@CavalcanteLeo
Copy link
Author

No, i havent, i will try this code...

The API returns me a lot of images already resized, so i choose witch one to use, depending of the iPhone resolution(100x100, 200x200, 500x500, 1000x1000, 1500x1500, 2000x2000)
in this particular case, im using the 500x500 ( but the print of the collectionview with the images was using 100x100 for testing)

@CavalcanteLeo
Copy link
Author

CavalcanteLeo commented Apr 30, 2016

Btw, where should I use this code? appdelegate or viewcontroller?

@mythodeia
Copy link
Contributor

should be before you make your requests. try the appdelegate

@CavalcanteLeo
Copy link
Author

On viewcontroller nothing changed... still increasing memory

@CavalcanteLeo
Copy link
Author

    "thumbnail": {
      "height": 100,
      "url": "https://timehi.s3-sa-east-1.amazonaws.com/post/160c6ef0a2d2db2a6502.jpg",
      "width": 100
    }

the 100x100 pixels image is about 4kb...

and increase a lot of memory

@mythodeia
Copy link
Contributor

why are you using SDWebImageManager's downloadImageWithURL:... and not [cell.imageView sd_setImageWithURL:...
can you try the demo project? do you see the same increase in memory there too?

@CavalcanteLeo
Copy link
Author

i cant show the image as soon as the dowload finish, i have to implement some logic before with the image...

@mythodeia
Copy link
Contributor

if you perform extra actions on the image you could use this

did you try the demo project? does it show the same memory increase?

@CavalcanteLeo
Copy link
Author

CavalcanteLeo commented Apr 30, 2016

i will try right now

@CavalcanteLeo
Copy link
Author

it still increasing memory with the code bellow:

[cell.image sd_setImageWithURL:downloadImg completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
    if (image) {
        BOOL isGrid = YES;
        if (self.headerProfile.segmentedControl.selectedSegmentIndex == 1) {
            isGrid = NO;
            cell.image.delegate = self;
        }else{
            cell.image.delegate = nil;
        }
        [cell.image setupImageView:post indexPath:indexPath isGrid:isGrid image:image];
    }
}];

@CavalcanteLeo
Copy link
Author

also have checked all strong and weak properties referencies... just to double check if the ARC is releasing all object correctly, but it's all right with it

@mythodeia
Copy link
Contributor

try the demo project with your API urls but without doing anything extra to the image after download. do you still see any increase in memory?

@CavalcanteLeo
Copy link
Author

I have to go now, but i will try in about 2 hours, tks by now

@bpoplauschi
Copy link
Member

@CavalcanteLeo any updates? Any chance you are using animated (GIF) images?

@CavalcanteLeo
Copy link
Author

CavalcanteLeo commented May 2, 2016

by changing setShouldDecompressImages to YES, in some benchmarks, my app performance went from 600mb to about 40mb

[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];
[[SDImageCache sharedImageCache] setShouldDecompressImages:NO];

and then from 50mb to about 6mb with this:

[[SDImageCache sharedImageCache] setShouldCacheImagesInMemory:NO];

captura de tela 2016-05-02 as 15 58 58

also set some other properties (no impact changed):

[[SDImageCache sharedImageCache] setMaxMemoryCost:1024 * 1024 * 1];
[[SDImageCache sharedImageCache] setMaxCacheAge:3600 * 24 * 7];

and on each viecontroller i clean the cache on viewDidDisappear and didReceiveMemoryWarning

-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [self clearImageCache];
}
-(void)didReceiveMemoryWarning{
    [super didReceiveMemoryWarning];
    [self clearImageCache];
}
-(void)clearImageCache{
    SDImageCache *imageCache = [SDImageCache sharedImageCache];
    [imageCache clearMemory];
}

but now, my problem is app performance, as i set ShouldDecompressImages to NO.
When i scroll my collection view too fast, my app freezes a bit

@mime29
Copy link

mime29 commented May 11, 2016

Did you try to activate the address sanitizer in your scheme? I have myself a crash because of sdwebimage when i activate it.

@ynotski
Copy link

ynotski commented May 26, 2016

We have also been monitoring an issue with RAM usage being way to high. We upgraded to v3.7.6 and followed the example above. e.g.:

[[SDImageCache sharedImageCache] setShouldDecompressImages:NO];
[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];
[[SDImageCache sharedImageCache] setShouldCacheImagesInMemory:NO];

What we found is this significantly increased the RAM usage by a factor of 2-2.5. We decided to downgrade to v3.7.3 and changed the following:

    [[SDImageCache sharedImageCache] setShouldDecompressImages:YES];
    [[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:YES];
    [[SDImageCache sharedImageCache] setShouldCacheImagesInMemory:NO];*** METHOD   UNAVAILABLE IN v3.7.3.

Our previous code using v3.7.3 was:

   [[SDImageCache sharedImageCache] setShouldDecompressImages:NO];
   [[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];

By downgrading to v3.7.3 and setting the two above methods to YES we saw a significant reduction in the the RAM usage.

@bpoplauschi bpoplauschi added this to the 4.0.0 milestone May 29, 2016
@SpaceStar2016
Copy link

I am using 3.7.3 and did the code like
[[SDImageCache sharedImageCache] setShouldDecompressImages:YES];
[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:YES];
[[SDImageCache sharedImageCache] setShouldCacheImagesInMemory:NO]
it didn't work for me. How to solve the problem??

@ynotski
Copy link

ynotski commented Jun 16, 2016

@SpaceStar2016
setShouldCacheImagesInMemory: is a method not available in v 3.7.3, so I am fairly sure you're not running v 3.7.3.

If you're using cocoapods to add dependencies to your project, change your podfile to:

pod 'SDWebImage', '3.7.3'

then run pod install

Remove the line:
[[SDImageCache sharedImageCache] setShouldCacheImagesInMemory:NO] or you will get compile errors.

Hopefully this will help.

@SpaceStar2016
Copy link

@ynotski I am sure I am using 3.7.3 I can code [[SDImageCache sharedImageCache] setShouldCacheImagesInMemory:NO] in my project.
0f0bbc40-6e71-4b40-884e-f201ed225846

@bpoplauschi
Copy link
Member

I think this issue is similar to #538 #586 and #1354.
#787 and 00bf467 should give you a good solution for dealing with large images. Together with the GIF handled by FLAnimatedImage, this ticket should be done now.

Closing. Let's see how this is with 4.0.0

@bpoplauschi bpoplauschi modified the milestones: 4.0.0, Future Oct 6, 2016
@dipkasyap
Copy link

Having same issue here, I am on xcode 9.4, swift 4.X, and tested on ios 11(Simulator)
screen shot 2018-06-12 at 6 21 50 pm

@smindia1988
Copy link

smindia1988 commented Sep 21, 2018

After lots of R&D and applying all kind of options for SDImageCache, I have finalized below options to set to avoid crash on heavy images load with the Best performance on RAM cache load:

Hope this will help you all !!!

Add below code into your AppDelegate class:

import SDWebImage

SDImageCache.shared().config.maxCacheAge = 3600 * 24 * 7 //1 Week
        
SDImageCache.shared().maxMemoryCost = 1024 * 1024 * 20 //Aprox 20 images
        
//SDImageCache.shared().config.shouldCacheImagesInMemory = false //Default True => Store images in RAM cache for Fast performance
        
SDImageCache.shared().config.shouldDecompressImages = false
        
SDWebImageDownloader.shared().shouldDecompressImages = false
        
SDImageCache.shared().config.diskCacheReadingOptions = NSData.ReadingOptions.mappedIfSafe

How to use:

//MARK:- Load Image with Activity Indicator

    func loadImageWith(imgView: UIImageView, url: String?) {
        
        imgView.sd_setShowActivityIndicatorView(true)
        imgView.sd_setIndicatorStyle(UIActivityIndicatorViewStyle.gray)
        if url != nil {
            imgView.sd_setImage(with: URL.init(string: url!), placeholderImage: UIImage.init(named: "ic_placeholder"), options:SDWebImageOptions.scaleDownLargeImages, completed: { (image: UIImage?, error: Error?, cacheType: SDImageCacheType, url: URL?) in
                
                if ((error) != nil) {
                    imgView.image = UIImage.init(named: "ic_placeholder")
                }
            })
        }
        else{
            imgView.image = UIImage.init(named: "ic_placeholder")
        }
    }

loadImageWith(imgView: cell.imgViewProduct, url: product.p_image)

@bpoplauschi
Copy link
Member

Thanks @smindia1988 for sharing these settings

@jokerYellow
Copy link

great work.Thanks @smindia1988

@bpoplauschi
Copy link
Member

@SDWebImage/collaborators should we list those settings to our docs or even README page? They might come in handy for a good number of our users.

@zhongwuzw
Copy link
Member

I suppose add a section of FAQ in WiKi page.

@bpoplauschi
Copy link
Member

Ok. I added https://github.com/SDWebImage/SDWebImage/wiki/Common-Problems#configuration-for-large-images-avoid-high-memory-usage

@ACode-Farmer
Copy link

@smindia1988
I am using version 5.0.1 that don't has shouldDecompressImages and shouldDecompressImages.
So how to avoid crash on heavy images?

@dreampiggy
Copy link
Contributor

@ACode-Farmer Use .avoidDecodeImage. You can also use the OptionsProcesser for global control instead of invidual image request control. See #2736

I'll update the Wiki soon about this. Seems out of date.

@ACode-Farmer
Copy link

Thanks for your reply. @dreampiggy
When I load multiple pictures, the memory is still too high.Use the same website for all pictures.(imageUrl = http://qiniu.ve-link.com//img/20191007/16d4d2e4e823e7449014aff5074096508372c2e9.jpg?imageView2/3/q/100).
SDWebImage @config:
SDImageCache.sharedImageCache.config.maxDiskAge = 3600 * 24 * 7; // 1 week
SDImageCache.sharedImageCache.config.maxMemoryCost = 1024 * 1024 * 20; //20 images
SDImageCache.sharedImageCache.config.shouldUseWeakMemoryCache = false; //Default True => Store images in RAM cache for Fast performance
SDImageCache.sharedImageCache.config.diskCacheReadingOptions = NSDataReadingMappedIfSafe;
SDWebImage Use:
[imageView sd_setImageWithURL:[NSURL URLWithString:obj] placeholderImage:nil options:SDImageCacheAvoidDecodeImage];
I tested three options setting:
1、SDWebImageScaleDownLargeImages
2、SDWebImageAvoidDecodeImage
3、SDWebImageScaleDownLargeImages | SDWebImageAvoidDecodeImage
Memory is still not reduced.

@dreampiggy
Copy link
Contributor

dreampiggy commented Oct 18, 2019

RAM usage for bitmap image usage, the fomula is really simple:

Pixel Count * 4.

For you demo image, it's a 3840px * 5120px, is 75MB.

The avoidDecode can never reduce this, it just reduce Memory Peak. For example, if you have 10 images, 2 on screen, 8 not. force decode will load 10 images in RAM in advance, to increase frame rate. If you disable it via .avoidDecode, you have to load images when they appears (This is the default behavior by UIKit/Core Animation), this will block main queue to decode, cause frame drop. It can get a relative small RAM usage before first display. If you can not understand this, Check FastImageCache, or my explanation (but in Chinese..). Or I can fill the wiki for this.

So, you'd better choose another idea for this, such as preprocess the image with lower resolution on Server, or using something on the Client like Wiki - Image Transformer. To scale down the resolution for images.

If you Really need to display large resolution. You can also try to use the CATiledLayer to display super large images. Which means, you don't load the image entirely into memory, you load them by tiles, the size is much more smaller than full size. Then, track the user's scroll and load another tile, etc. This is just the technology used by Map apps (For example, a full map bitmap image may be 100000*100000 pixels, this can not been hold in RAM at all).

@dreampiggy
Copy link
Contributor

@ACode-Farmer Update the documentation, see Wiki - Optimization for large images

@ACode-Farmer
Copy link

Thanks @dreampiggy
Which version are these settings in?

@dreampiggy
Copy link
Contributor

The documentation is updated to latest SDK name. The options processor is available in 5.1.0, the other is available in 5.0.0. See wiki: https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#options-processor-510

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests