I've created a small photo gallery which is presenting a new view controller with a larger version of the photo and some additional text when it is clicked:
The problem is - after going through a handful of images - the application crashes due to overuse of memory. I attempted to resolve this by compressing the images in order to leave a smaller memory footprint, but the issue remains and I'm not sure what else I can do to resolve this issue.
Also - there is almost no code to doing this since I'm using storyboard's push segues as well as the built in navigation item to go back between viewControllers.
P.S.
If you feel source code is necessary to provide insight in this instance - it can be found here:
https://www.dropbox.com/s/q1qq8pq4tzv8wyo/EXAMPLE%20BUILD.zip?dl=0
To resolve this issue you have to use this trick; Put a "placeHolder" image in your cell's imageview in "StoryBoard". Don't load the images all at once in your "ViewController", load them one by one by running a loop or in your "cellForRowAtIndexPath()" method and add a delay in each iteration (Load first image then add a delay, load second image and add a delay, then for third one and so on up to the last image).
If you want to know how to add a delay then check this link:
NSTimer - how to delay in Swift
To resolve this issue I simply resized the images - I noticed I accidentally used a gigantic (6000 x 4000) image and even though I compressed the images iOS had to crunch pretty hard to resize them into the view... thereby causing the memory leak and subsequent crash.
Resizing them to 600x400 did the trick.
Related
Goals:
Programmatically load first image (approx 94kb) into an ImageView in the main storyboard from the Assets.xcassets folder (see code below) - works perfect
Then when you load a second image (same size) into the original UIImage it causes the iOS app to crash.
Here is my code:
mainImageView.image = UIImage(named:"FirstImage.png") // load first image, no issues
Then if you programmatically load a second image into the same UIImage it causes the device to throw a low memory warning and the iOS crashes the app:
mainImageView.image = UIImage(named:"SecondImage.png") // load second image
After reading a number of answers on SO and other articles (see below), the best way to manage memory when you are loading multiple images into an animation array is to use the contentsOfFile: imageName instead of the UIImage(named:"FirstImage.png")
See Article here:
http://www.alexcurylo.com/2009/01/13/imagenamed-is-evil/
And secondly Apple states the following:
If a matching image object is not
already in the cache, this method locates and loads the image data
from disk or from an available asset catalog, and then returns the
resulting object. The system may purge cached image data at any time
to free up memory. Purging occurs only for images that are in the
cache but are not currently being used. In iOS 9 and later, this
method is thread safe. Special Considerations If you have an image
file that will only be displayed once and wish to ensure that it does
not get added to the system’s cache, you should instead create your
image using imageWithContentsOfFile:. This will keep your single-use
image out of the system image cache, potentially improving the memory
use characteristics of your app.
https://developer.apple.com/documentation/uikit/uiimage/1624146-init
Lastly, upon receiving the Memory Warning you could also create the following function:
func applicationDidReceiveMemoryWarning(application: UIApplication) {
NSURLCache.sharedURLCache().removeAllCachedResponses()
}
Hope this helps someone else :)
I'm developing an iOS app that displays more than 1000 images -locally stored-, After using it for some time, app crashes due to memory leak.
I tried Profile tool, but couldn't figure out where the issue is, I'm displaying these images in both tableView and Icarousel. scrolling through app, memory increases but doesn't seem to be released.
Things I've already done:
Resizing Images(This just delayed the crash).
Clearing dictionaries and datasources- didn't make any difference-.
I tried Using "contentsOfFile" instead of "named" property when creating image- didn't make any difference also-.
Clearing the image in reusable func in the tableViewCell -nothing changed-.
Note:
I'm using AdMob, but even when I don't use it, memory still leaks.
As I understood you're storing your images in NSArray or something like that to represent them in table view.
Try to use NSCache to store your images in RAM. It will automatically clean used memory if it'll need.
I'm really struggling with running out of memory in my app. The are the basic operations that I'm performing, as specified below. Note that whenever a user takes a picture with the camera, I save two different versions of it--one is a preview (for fast loading), and one with high quality for zooming and marking up later.
Here is a list of my order of operations:
At app launch, show thumbnails of images that have been taken in the app (obviously, at first launch of the app, this list is empty).
Touch camera button to launch the UIImagePickerController
User takes a photo and saves it (again, a preview is saved and a full scale photo is saved)
The list of thumbnails refreshes and shows the new preview image. Again, the overall size of "Image IO" in the VM Tracker instrument is still very small (increased by maybe 0.5MB tops).
User touches one of the preview images, which launches a different view controller that does the following:
Create new UIImageView, load the image, add as a subview to View Controllers view
Suddenly, "Image IO" jumps by 30MB.
The wouldn't be a big deal, but when I go back (navigation controller pop), neither the "Image IO" type nor the "Dirty" type decreases in size. It's as if the UIImageView is not being destroyed. Every time I push this view controller and load an image, the size increases by 30MB, and popping never decreases it.
I'm using ARC, so I'm not calling release myself, but I would expect that it would be destroyed when I pop the view controller.
Just FYI, the settings I'm using for saving the preview and the full image are:
Preview: [UIImageJPEGRepresentation([UIImage imageWithImage:image scaledToSize:CGSizeMake(300, 400)], 0.4f) writeToFile:previewPath atomically:NO];
Full: [UIImageJPEGRepresentation(image , 0.8f) writeToFile:imagePath atomically:NO];
My main concern is (1) figuring out how to get rid of the memory used from the UIImage after I pop the containing view controller, but I'd also like to know (2) why the image is 30MB when loaded.
i'm worked on image editor app and this help me lot for reduce memory use.Try this
don't load images with [UIImage imageNamed:] for load image in ImageView,it's cause memory issue when no.of images are more,
use this,
NSString * imgpath= [ [ NSBundle mainBundle] pathForResource:#"imageName" ofType:#"png"];
ImageView.image=[UIImage imageWithContentsOfFile: imgpath];
As suggested by #Matic Oblak...
(1) I have already seen similar problem with image view, try setting its image to "nil" before popping the controller and see if the problem persists.
RESULT: I explicitly set the UIImage AND the UIImageView to nil (not sure if both are needed), and sure enough, it released the memory.
I am creating an app with an UIViewController which displays other UIViewControllers with the MPFlipTransition inside it. It's like a little book on iPad.
The UIViewControllers inside are created each with xibs with 4-5 UIImageViews inside and some of those images are animated with CoreAnimations ([UIView animateWithDuration] blocks)
I remove all the animations in the viewDidDiseappear function with the QuartzCore function removeAllAnimation on each animated layer.
But when I'm testing the app on an iPad 3, it works properly, but on iPad 2 it crashes at about the 8th page change.
I've made a profiling with Instruments and found that the real memory usage was increasing everytime I turned the page (when the MPFlipTransition appears). But even if I remove from the superview the previous views, the real memory usage is not decreasing. I thinks that it created the crash on the iPad 2 because the crash come when the real memory usage is passing the 400 Mbytes value (and the iPad 2 has only 512MB...).
What do you think about this problem ? Any help ? I'm using ARC for memory management...
Thanks for you help ! Feel free to ask if any need of precisions...
let me come to issue fast. There is no problem in my code so far. My only concern is Memory management. Let me make my app logic clear.
When App is launched globally NSmutableDictionary is declared and nearly 300 images are added to that Dictionary with various keys and images are added using pathForResource:ofType method.
After my rootViewController loaded my 35 custom UIViews are added to same global dictionary with another key.(this rootViewController will not be used often)
I have 4 ViewControllers where i am going to use this UIViews and images to all ViewControllers from the global dictionary.
I release the view and making it to nil when moving to another viewController.
My issue is when i move between ViewControllers fast ( 1 --> 2 --> 3 --> 4 -->1 ). it gets crashed if I do like this for 4 - 6 times.
If I move slowly it gets crash after 10 - 15 times.
I Dont know the reason why it gets crashed even my Live bytes is max 5 MB. all i get from console and also from Device log is Received Memory warning. No leaks and No Dirty size or resident size while using Instruments.
While running in simulator i dont get this issue only on multiple devices i got this issue.
I have following doubts
Whether its good to add everything in global dictionary. My idea is to reduce the loading time for every ViewControllers
for reusing same images can we use pathForResource or image named method..
Thanks in advance ...
So your question:
Unknown reason to receive Memory Warning
First reason:
When App is launched globally NSmutableDictionary is declared and
nearly 300 images are added to that Dictionary with various keys and images are added using pathForResource:ofType method.
Second reason:
After my rootViewController loaded my 35 custom UIViews are added to
same global dictionary with another key.(this rootViewController
will not be used often)
Other questions:
Whether its good to add everything in global dictionary. My idea is to
reduce the loading time for every ViewControllers
No, it's not... Lazy Initialization?
for reusing same images can we use pathForResource or image named
method..
You can use whatever you want, as long as you use it when you actually need it.