In my app, it seems like CG image is eating up a lot of dirty memory:
Is there any API to call to flush all the dirty image in the memory? In the code I am just resizing the images with this library, and I am putting only about 20 MB worth of pictures (no more than 1MB each) on the screen.
It works okay on regular iPad but it crashes on iPad mini. Can anyone point me to the right direction?
Edit: Static analyser said the project is fine. Low memory crash log is here.
Related
I know this is a stupid problem, but this is my first real app that I have to make, I have no one to ask and I looked up this problem and found no other similar problems.
My app crashes on real devices with no exception. I saw in the simulator that uses too much RAM and after a while I got to the conclusion that the pictures I am using are to blame.
The app is structured in this way: it has 8 viewControllers for different things: for example, it starts with one which lets the user select the avatar with which he/she will play and here I have two pictures, next is a viewController which shows the stats for that avatar and here it is another picture and so on. The problem is that each picture uses 40MB of RAM to be displayed and things add up so the app uses more than 300MB of RAM when the user gets to the gameviewCOntroller where the game is. Because of this, on devices like iPAD 2 or iphone 4 it crashes, but not on iphone 5.
I tried to set the images both from "images.xcassets" and from a ".atlas" folder, but the result is exactly the same. The pictures have a dimension of no more than 1500x1999px, they are in png format.
Also, I saw that if the app were to start directly into the gaveViewController it would use 180MB so the other viewController remain in memory or something like that. Should I "clear" them or something similar?
//-------update-------
This is what I got from Instruments:
Memory is a big deal on mobile devices, there is not a clear answer to you question, but I can give you some advices:
If your images are plain colors or have symmetric axes use resizable images. You can just use one line of pixel multiplied by with or height to cover the entire screen using a small amount of memory
Image compression doens't have effects when the image is decompressed. So if you have a png that is 600kb and you are thinking that converting in a 300kb will lower memory usage is only true for "disk space" when an image is decompressed in memory the size is widthXheightXNumber_of_channelXbit_for_channel
resize images: if are loading a 2000px square image into memory and you show it inside an image view of 800 px square, resize before adding it.You will have just a peak while resizing, but later it will use less memory
If you need to use big images, use tiling techniques such as CATiledLayer
If you don't need an image anymore get rid of it. It's ok to have an array of path to images, but not an array of full uncompressed images
Avoid -imageNamed it caches images and even if Apple says that this cache is released under memory pressure, you don't have a lot of control on it and it could be too late to avoid a crash
Those are general advices, it's up to you if they fit your requirements.
You should definitely follow Andrea's advices.
Additionally you should consider setting the image size to exactly what your need is. You're saying that you've tried to set them from xcassets so you have full control over the images you're loading, which is great (compared to downloading an image that you cannot modify).
I highly suggest you read some documentation on using Asset catalog files. This will allow you to have high-resolution image for bigger screens that also have more memory, and smaller ones for older devices, which is what you want here.
Also, note that 1500x1999px is still a very big size for most mobile devices.
More links about screen-size:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html
http://www.paintcodeapp.com/news/iphone-6-screens-demystified
I'm testing on an iPhone 4 running iOS 7.1 attached to Xcode 5.1.1. I don't understand why I am getting memory warnings and even crashes when instruments shows my app is only using a few megabytes and there is plenty of memory free (see attached). Any ideas?
Update:
In instruments, as I suspected, I found no leaks, but the "Anonymous VM" size seems unduly large and filled with image data. Each table cell in my app displays a JPEG. Perhaps I should be pre-scaling these images and that is the cause of the large Anonymous VM size... More investigation to be done.
It turned out images displayed in UIImageViews in each and every table cell were being stored in memory at their full size, not the scaled size (size of the UIImageView). This only showed up in the "Anonymous VM" in Instruments (since iOS only stores references to your images in your application heap and the actual image caches are in system memory it seems), not in the basic memory usage displayed in Xcode. I resolved the issue by pre-scaling my images before putting them into the UIImageViews of the table view cells. There were no leaks.
Instrument is sometimes imprecise about the real memory used. The best way to measure is to print the memory usage on the console.
I found the code on this thread: Programmatically retrieve memory usage on iPhone
I have an app that has 12 images contained in an array. All these images are displayed at the same time on the screen. (1 view - 12 much wider and higher images (UIImageView's) one on another. When user does something, app moves the images, thus the view displays different scenes)
The images themselves are not too heavy (it is about 2500x5000 in size, but the whole folder with images is around 3.5 MB).
After loading, the app consumes 355 MB.
When I put breakpoint in viewDidLoad (and all images are loaded at that time), xcode shows that the app consumes only 9 MB, but in viewDidAppear it is 355 MB.
What is the reason of it? And how can I store images compactly? (As I assume that the problem is in the images).
Thank you for any help!
An image open will occupy something like : H x W x number of channel x number of bit for channel, the file size is another thing, because images are compressed according to their type. Your images are 50Mb each one in memory.
The only way is to resize the image before displaing them. There are plenty of image resizing categories online, just google a little bit.
The other suggestion is to not load all the images togheter, just bring in the array the file path, and instantiate the image lazily.
If you need to use hires images you should look for CATiledLayer and tiling techniques.
These images probably cannot be displayed all at the same time onscreen, so you may want to load them only when necessary.
If you still need to display them all together onscreen, think about reducing their size.
Still, 355Mb is huge. Are you doing anything else in that application, that might use up all of that memory?
In Xcode go to Product->Profile. You will find there a lot of useful instruments which will help you to find problems with memory, CPU or battery usage. However, check it if you haven't seen it before.
My app crashes with low memory warning on device, even though the max live bytes in instruments is 3 MB tops. I do use a lot heavy PNG's in my app(in about 20 ViewControllers) , I believe ARC should've taken care of it.
Here is the screenshot.
Reduce size of heavy png files. Png file must be good in resolution but size must be less not more than 2 MB.I also had the same problem but used Three 20 Framework which solved my issue because it manages Images files allocation perfectly. Now a days it seem Three 20 is not getting updated but still you can try it in a sample app if you want . Here is the link :http://three20.info/
I figured it out myself. The problem was that I was doing animation using a bunch of PNG's.
So when using this
image.animationImages=imageFrames;
it was caching all the images in memory each time it was called, which led to dirty memory filling up and crashing the application. So, after using it each time to release the image cache we need to do this
image.animationImages=nil;
Currently I am writing an iPad app. I am using a lot of images in this app around 40 MB of images!
This app works fine in simulator but crashing on device. I think the problem is with memory.
I wanted to know how much memory I can use on iPad?
Thanks
Saurabh
Remember that 40MB of image files on disk is far more when put in memory. On disk they are compressed but once you load it into memory you use just as much memory as a uncompressed image. If I remember right its (width x height x (bits per pixel/8)) = mem usage so for a full screen image (1024x768x(16/8)) = 1,572,864 so around 1.5 MB of RAM while on disk it may only be a couple hundred KB.
The iPad has 256 MB of memory, and of which, only around 100 to 120 are usable in an application. Note that this number is variable as the VM releases memory from previous applications, and could be less if you're using apps like iPod in the background.
My suggestion, look at what you can do to reduce the size of your images, through different resolutions, lower quality images, or such.