0

I am using Firebase to host and download images for my app. Each image on Firebase ranges from 200kb-400kb, and the user downloads about 12 at a time as they scroll through a collectionView. When I launch the VC that downloads the images, my app goes from using about 100mb of memory to 650mb of memory from downloading 19 images total. The images in questions are JPEGs and have been compressed quite heavily before their upload to Firebase. These images are stored in an NSCache, and clearing the cache brings the memory usage back down to around 100mb.

What is going on? Here is some code that may help?:

class TripOverviewCell: UICollectionViewCell {

@IBOutlet weak var imageView: UIImageView!

func updateUI(photo:Photo, image:UIImage? = nil) {
    //Call when preparing to show image
    if image != nil {
        print("Loaded from cache")
        imageView.image = image
        photo.assignImage(image: image!)
    } else {
        let url = photo.imageUrl
        let ref = FIRStorage.storage().reference(forURL: url)
        ref.data(withMaxSize: 5*1024*1024, completion: { [weak self] (data, error) in
            if error != nil {
                print("Unable to download image")
            } else {
                print("Image downloaded")
                if let imageData = data {
                    if let image = UIImage(data: imageData) {
                        self?.imageView.image = image
                        photo.assignImage(image: image)
                        TripsVC.imageCache.setObject(image, forKey: photo.uid as NSString)
                    }
                }
            }
        })
    }
}
}
Cody Lucas
  • 682
  • 1
  • 6
  • 23
  • 1
    When you're talking about the memory usage on the app, you're referring to RAM correct? Just because an image is 200kb doesn't mean it'll use 200kb of RAM to display it – Andrew Brooke Mar 17 '17 at 18:09
  • That is correct, RAM. Of course I understand it will need to use more resources to display it, but up to 1500x the size of the image? Additionally, the size of cache itself is about 550mb from 19 images. Clearing the cache puts it back at 100mb of RAM in use. – Cody Lucas Mar 17 '17 at 18:13
  • To display an image, it will have to be converted from the stored bytes into the displayed pixels. So if you have a 3000x2000 image that you compressed down to 200Kb, it will still have to be uncompressed into 6 megapixels. If each pixel is 4 bytes (rgba), that's 24MB. Load 19 of those and you're getting in the rough range you're talking about. – Frank van Puffelen Mar 17 '17 at 18:25
  • That answer makes sense, but it still leaves me an issue. How do I deal with displaying a bunch of photos and it not taking 1gb of memory to hold 40 small images in memory? – Cody Lucas Mar 17 '17 at 18:29

1 Answers1

1

As Frank commented, displayed images take up a LOT more space than just the data for the images. My error lay in the fact that I was caching UIImages, which is the full displayed image. Instead, I should have cached the data and then created images from that data where I need them. Memory usage is down from 550mb to about 20mb.

Cody Lucas
  • 682
  • 1
  • 6
  • 23