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

Add a secondary weak memory cache to improve speed and decrease memory usage when reusing previous images #791

Closed
wants to merge 3 commits into from

Conversation

DimaVartanian
Copy link

Hey guys! This addition to the project can improve speed and significantly reduce memory usage in cases where the regular memory cache has been cleared but images it once held need to be reloaded.

Consider the following case:

  1. An image is loaded and retained by ImageView1 (as well as added to the memory cache and disk cache)
  2. Sometime later, the memory cache is cleared (possibly due to a memory warning)
  3. ImageView2 loads the same image ImageView1 loaded earlier. The memory cache does not contain it so it is either reloaded from the disk cache, or downloaded again. In either case, a brand new UIImage is created, effectively resulting in 2 copies of the same image sitting in memory.

With this addition, all downloaded images are also referenced by the secondary weak memory cache (so they are not retained) and reused when possible to prevent a single image from ever being duplicated by SDWebImage.

Sample
To see the fix in action, you can download this sample project: http://cl.ly/2J3s0z2e2m2C
Move the comment in the podfile to switch between my fixed fork and the current latest commit in master.

Open the app and trigger the case by pushing a new view and then triggering a memory warning. Repeat this and watch the effects in Instruments: The allocations for UIImage continue to rise (In the Allocations instrument) and the Virtual Memory usage (in the Memory Monitor instruments) rises by several mb with each additional load. Switch to my fork and you will notice the UIImage only ever gets created once no matter what you do, and memory usage remains relatively static (rising very slowly due to multiple views and view controllers being allocated).

…ference previously cached object that are still alive and reuse them instead of redownloading them or pulling them out of the disk cache. This is faster and uses less memory.
@DimaVartanian
Copy link
Author

After thinking about this a bit more I could think of only a single case it would not really work with but should still handle, which is when you are trying to remove an image from the memory cache because it is considered expired and should not be reused, rather than for memory purposes. In these cases, the weak pointer should also be cleared so that the "expired" image does not get reused by the cache. Adding support for this could be as simple as adding an extra flag to the removeImage... methods in SDImageCache.

What do you guys think?

@DimaVartanian DimaVartanian changed the title Add a secondary weak memory cache to improve speed and decrease memory usage Add a secondary weak memory cache to improve speed and decrease memory usage when reusing previous images Jul 6, 2014
@bpoplauschi bpoplauschi added this to the 4.0.0 milestone Jul 10, 2014
@DimaVartanian
Copy link
Author

Any thoughts on this @bpoplauschi?

@bpoplauschi
Copy link
Member

@DimaVartanian Sorry I didn't respond earlier (lack of time). I will look at this soon.

@bpoplauschi bpoplauschi modified the milestones: Future, 4.0.0 Sep 29, 2016
@dreampiggy
Copy link
Contributor

Looks great. A weak map to keep the reference to the UIImage instance without touch the reference count. I will consider add this feature later.

@dreampiggy
Copy link
Contributor

This PR is merged by #2228. Thanks for your suggestion :)

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

Successfully merging this pull request may close these issues.

None yet

3 participants