I have an app with feed like instagram. When I scroll it loads more and more images.
So at one moment iOS sent me memory warning and I don't know what i should to do.
If I make array(feed) is equal to nil, nothing happens
here's my object allocations:
You are supposed to dealloc any unneeded or recreate-able resources, like some images off of an array in which you might keep of all images your app has downloaded since the creation of mankind*.
*note that this is highly not recommended.
Related
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.
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 write a table view/collection view to show lots of photo.
I use dispatch queue to load photo from Internet and use NSCache to cache photo (for not loading photo from internet again).
when I loaded over 2000 photo, app received memory warning.
I tried to release the content of nscache in didreceiveMemoryWarning(), or set the nscache delegate to let nscache to auto release nscache content.
after releasing the content of nscache and I scrolled to the top of the table view,
sometimes: the thumbnail load different images several times (show
image1, image5, image 6)
sometimes: the thumbnail won't show anything
I guess what caused this happened is --> using dispatch queue to show thumbnails in table view
but I don't know how to fix it!!
anyone knows?
or is there any better way to show lots of photos(over 3000)?
thank you!!
I appear to have a memory management issue when I create UIImage instances the CGImages are not being released.
I have a paging UIScrollView to scroll through a series of JPG images. Below is my entire class that is a page view in the paging scroll view.
The code is being run on the main thread. The code uses ARC. I have tried loading the images using imageWithContentsOfFile: (returns an autoreleased object) as well as initWithContentsOfFile:(returns a retained object). I have tried #autoreleasepool and using performSelectorOnMainThread to ensure that the code is being run on main thread as suggested in other posts.
When scrolling through the images memory usage just grows until the app gets terminated as illustrated in the screenshot from instruments. Note the high allocation to image io.
Screenshot showing virtual memory usage
In the following screenshot it can be seen that the GTGImageScrollerPageViews, UIImageViews and UIImages are being deallocated. Notice there are Transitory objects for these numbering in the high 300's. However the CGImages are not being released and the number of CGImages living is in the high 400's and 0 Transitory.
Screenshot showing allocations
EDIT: Previously I had been recycling and re-using GTGImageScrollerPageView instances in the ScrollView as is the common pattern for scrollviews like this. In order to simplify while trying to debug this problem I allow the entire GTGImageScrollerPageView to be deallocated after it has been displayed in the ScrollView. As you can see in the second image above, there are only 4 GTGImageScrollerPageView living and 377 transitory, there are also 388 UIImageViews and 389 UIIMages listed as transitory so it appears that the UIImageViews and UIImages are being deallocated fine.
If I manually release the CGImage with CGImageRelease (Commented out in the code below) the CGImages are released. I know that I should not do this because I do not own the CGImage but this is useful to verify that this is where the problem is occurring. The screenshots below show the same code tested in Instruments but with CGImageRelease uncommented.
Screenshot showing virtual memory usage with CGImageRelease used
Screenshot showing allocations with CGImageRelease used
In the profiling outputs where CGImageRelease is used, you can see that the correct number of CGImage objects are Living and Transitory and that memory does not grow unbounded. Furthermore the app does not crash during usage with CGImageRelease used.
If this were some system caching of CGImage then it should release the memory when a memory warning is raised, but it doesn't. Memory just continues to grow.
What here could be causing this unbounded growth in memory?
Here is the code for the page view
EDIT: In response to comments I have updated the code to simplify further thus eliminating distractions such as ivars and properties that are not needed to demonstrate the problem. The problem remains unchanged and the results are the same when profiling. I have also added in the NSLog which also outputs the thread. I do see the dealloc being called as expected on the GTGImageScrollerPageView and it is always thread #1 and the call to displayAspectThumbImage is always on thread #1.
I really dont believe that there is anything wrong with the code that is presented here and this is confirmed by the generous effort of Rob. Something else is causing this but all the code related to loading and displaying the image is here; there is no other code in effect here. The only other notable thing that I could think of raising is that the displayAspectThumbImage method is called from scrollViewDidScroll and scrollViewDidEndDecellerating methods of the scrollview delegate but the fact that the methods are called on the main thread should exclude autorelease issues due to being run on another thread.
I have checked and NSZombies is not enabled and there are no Zombies increasing my memory usage. Indeed when the CGImageRelease method is called the memory usage is pretty flat as can be seen in the screenshot above.
#implementation GTGImageScrollerPageView
- (void)dealloc {
NSLog(#"%s %#", __PRETTY_FUNCTION__, [NSThread currentThread]);
}
- (void)displayAspectThumbImage:(NSString *)path {
NSLog(#"%s %#", __PRETTY_FUNCTION__, [NSThread currentThread]);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.bounds];
[self addSubview:imageView];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];
[imageView setImage:image];
//If uncommented CGImages are disposed correctly
//CGImageRelease([imageView.image CGImage]);
}
#end
Tested on:
iOS 6.1.4
iOS 5.0.1
Really sorry to be answering this question myself but thought it would be useful to share my experience.
It turned out to be a category on UIImage that was part of a third party library I was using. I wont name the library as I have tested with the latest version and the problem is not there so there is nothing to gain by naming the library.
It is particularly strange as the library was not being used anywhere near the code that was leaking. It was only being used in one place in the whole project, but any time I used a UIImage it seems that it was affecting the UIImage instance. The mere presence of this category in the project was enough. This came as a real surprise.
The way I solved this was to begin by simulating the scenario in a new project and found that the code was not leaking there. I then migrated the code a little at a time and when I moved the categories across the leak appeared.
Huge thanks to Rob for his generous efforts to help me with this and even though he did not provide the solution directly, talking to him was really helpful in solving the problem. Nice to know there are such cool people out there.
I did a simple infinite scroller using your code and after scrolling through nearly 100 images the memory usage was, as one would have expected, thoroughly uneventful:
Looking at your source, I would have recommended a few little things (e.g. I would have put aspectImageView into a private class extension rather than the .h, I assume you're setting pageIndex from the calling routine but I'd add it as a parameter of displayAspectThumbImage, I would have made aspectImageView a weak property and refactor the code accordingly (e.g. create image view, add it as subview, then set the weak imageview property to point to this object), etc.), but none of those have direct bearing on your issue here.
Bottom line, your problem does not rest in the code you've shared with us.
Try to use property instead of ivar.
#property (nonatomic, strong) UIImageView *aspectImageView;
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.