I have created an iPhone Application where I have managed to handle leaks using the Profiling tool of XCode.
I have a gallery of images shown in UIScrollview when I load the view.Images in the gallery changes on each load of the view of iPhone.
I managed to remove the leaks using the profiler, but what happens now is memory gets increased by some amount on each load. I really cannot get why the memory increases on each load,when there are no leaks in the application.
Can anybody help me in finding this issue?
If you don't have leaks in the app it does not mean that your memory management logic is correct.:d
Do an analyze from tools menu.
And read again your code to see where you can release objects that are no longer needed.
In a gallery you should load only what users sees and the previous and next image only one step.
So if you are displaying one image on screen load only the next and the previous if you have one. So you will have only 2 or 3 images alive in memory. When user scrolls load next and release the previous, you can cash more than one image like 2 3 4 depending on the size,
Related
I have a universal app that is essentially a list of articles with images and text, and menu under the left side of the app. I have google analytics in, as well as parse's framework.
The only difference between the app on the iPad and iPhone is that the side menu is always visible on the ipad, and a few interface objects are moved around. (different cell layout for the list--same content, though).
The images are loaded asynchronously using a set of classes that I wrote to download/save in an NSCache object and on the disk using a NSOperationQueue. (disk cache is wiped when the user leaves the app). The NSCache is set to max out at roughly 10 mb. (assuming image size is image hight*image width * 4 bytes per image). (code here is identical for both, so it shouldn't be the culprit, but it is a large chunk of the apps memory use).
I was having some trouble with memory warnings/crashing on an older iphone4 running iOS 5.0, so I ran the app with the Activity Monitor Instrument, and noticed something very odd:
On the iPad (an iPad 2 running iOS 5.1) the app launched, loaded the images that were visible immediately, and was using about 16mb of memory.
On the iPhone4 it launched, loaded the visible images and was using about 35mb of memory--way more than I would expect.
In order to check if it was an OS memory issue, I also ran the app on an iPhone5 running iOS6 and it used about the same amount as the iPhone 4.
I checked my media and the storyboard files to see if anything was different at all, and I could not find anything that could change the memory usage in any significant way.
Is there any way to reduce the memory use of the app on the iphone? I can think of no reason it would use so much memory.
Very difficult to see.. as one person stated pay attention that retina devices will use more memory according to the source, if in the bundle you set #2x images it will load them, and they use more memory.
Have tried to profile the Virtual memory using allocations?
Using memory is usually fine even if it fires a memory warning, the problem is how you respond to it, when it comes does it free enough memory? try with the simulator to simulate a memory warning. Pay attention that sim uses more memory than device.
One other point is that since ARC is difficult to create leaks, but it's easier to create retain cycle and abandoned memory. A correct object life cycle should end with object deallocation.
You say that you use NSCache and load images from the net async, I've got 3 suggestion for you :
Do you know the original image size on the source? maybe on the iPad source images are smaller than on iPhone. A correct approach after you download an image will be resize it according to the really needed size (I'm mean redrawing non just stretching) you ca achieve that with Quartz or using ImageIO
I never understood the behaviour of NSCache after memory warning, Apple says that it will flush the memory but after some test on iOS4 (I don't know now) I don't agree. I've created my own subclass that observe for memory warning and flushes memory
Are you totally sure that you are getting back image from the cache ?
//The point
I gradually load many objects (UIWebView) to the memory and after a while it crashes. Please Help
//Details
I have a UIScrollView with horizontal paging, wherein each page (with a separate view controller) contains a UIWebView with disabled user interaction. At first only webview #0 on page 0 gets loaded and as I advance through the pages the app gradually sends requests to load specific data. Downloaded data stay in memory.
After I load about 20 Webviews from internet source, my app freezes and crashes. If I use a dummy html string stored on the device, this happens after I load about 50 webview. But the problem persists.
I fixed much of the leaks and am only left with Mallocs. Since the problem does not occur with low quantities of UIWebviews Loaded I assume that I have to change my code to say 3 webviews and reuse them. But I don't know if that'd fix the issue. I have developed several apps before which don't crash and this is a unique case.
I store pointers to webviews and some other elements inside every Webview (such as labels) in arrays. The arrays get incremented in count with every new page loaded.
I use xcode 4.3 and a jailbroken iphone 4 to develop. I turned off requiring signatures in my xcode as a result of which the app gets copied onto my phone yet fails to attach to process. I cannot debug on my phone. My app works well in simulator but crashes a while after I launch it on the phone by tapping the icon.
From what I am able to describe as so, what do you think might be the problem?
Thanks
Yes, certainly having too many UIWebViews will cause a crash due to low memory. I'm not sure what your reason is for having multiple UIWebViews, but I would follow through with your idea to reuse a smaller amount of them instead of creating several.
Based on your device not crashing when you use a small amount, I would say that the problem lies in the use of too many UIWebViews and not in a compatibility problem with your jailbroken device, for example.
WebKit is notorious for its memory hogging. It mallocs large blocks of memory and fails before giving you the opportunity to release other resources. One UIWebView is bad enough. I've had this problem in apps with as few a 5 UIWebViews, let alone 50.
There are a couple of things you can try. One, if the web pages aren't too complicated, you could use a replacement view such as DTCoreText to render them. If you have to have webviews, you could cache the various HTML contents and re-render using one UIWebView.
You only need to use three UIWebView's for paging. Lets say the user is on page 2 (page 1 is the left page and page 3 is to the right). When the uses swipes to page 3, you could just display the web view currently on page 1 on page 3. You need to re-load the proper html when the user swipes between the pages.
With some caching of the web content, speed shouldn't be a problem once the stuff is downloaded.
i m facing big problem with system libraries allocations.
i didn't get any leaks from my application still so much allocations.i attached various screen shoots. in my application using custom picker which get all images from assert library.which are pick from picker showing images on scroll view.
its screen shot when my app with 35 images on scroll view.if again i pick images from custom picker allocation increased.i am seeing object details its all related to frame Work allocations.not from my application
see the allocation object list response library is DYLD.
its my leaks screen shot
how can we release these allocations? please help me out ?
Just because you have no leaks doesn’t mean you are managing memory correctly. What you have is what I call memory bloat — you are retaining it longer than you need to. (A leak is allocated memory with no references. Bloat is allocated memory that has a reference but should have none.)
http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/ will give you some good strategies for using Instruments to find them. (This is a very credible source, so far as I know he still works at Apple.)
make sure your application has no leaked objects and they will also disappear in instruments. For sure its pointing to a system library but it is always a result of your bugs. Select one of them and open the right view. Probably it will show you the right code stack and the allocated line of code.
The other thing you can do: run the static analyzer Product->Analyze it will find all (at least most) your leaks ;)
I'm using Instruments with the Allocations instrument. I'm testing only a fixed interaction with my app.
I have a navigation controller which goes 4 stages deep. The first two stages are standard table view controllers and the last two are custom controllers with dynamically loaded images.
So I run my app in instruments (via Run with Performance Tool -> Allocations) and do the following interactions:
1. App Loads
2. I wait a bit until allocations graph stabilizes
3. I tap/push into my navigation controller until the deepest level.
4. I wait for the images to load and for the allocations graph to stabilize.
5. I tap back out of the navigation controller until I'm back to the root level.
6. I wait for the allocations graph to stabilize.
7. GOTO 3.
Now what I've noticed is that between each iteration from 3 to 7 the allocations graph shows a slightly higher value. So the overall allocations are increasing even though I'm doing the same thing and all the view controller's deallocs are being called.
So the timeline looks roughly like this:
1. Start: 1mb
2. Push controllers/Load images: 4mb
3. Pop controllers: 1.1mb
4. Push controllers/Load images: 4.1mb
5. Pop controllers: 1.2mb
6. ... etc ... (always increasing slightly)
So my question is does this mean I have a leak or is this normal? Also what does the allocations graph data actually represent? And why is the value increasing even though I'm popping back out to the initial state? I'm worried that if my app runs long enough it will consume too much memory even though all the user is doing is pushing and popping view controllers.
Any thoughts would be helpful.
Is this in the simulator, or on the device?
As it's good to verify a problem exists on the device, as some system libraries release memory more often on the device than in the simulator.
If Leaks shows nothing, it's because you are still holding a reference to memory somewhere even if you don't think you are. To help track that down, highlight a small portion of the graph where the memory is increasing, and select "created and still living". Now you can see just the memory allocated, and start to track down just where the issue is.
If you have the newest iPhone SDK, the version of Instruments it comes with (2.7 I believe) has a HeapShot feature. You can watch some of the WWDC '10 videos for more information, but essentially you take a shot the first time you pop controllers and then again when you pop a second time. It will show you any memory allocations that are different at the two moments.
You probably have a leak. Check the leaks instrument which can help you find them.
Yes, this is a leak. One of your view controllers along the line is missing something.
If you are loading images then there is a good chance you are using [UIImage imageNamed:] that causes the system to cache and may be a cause of your memory use. But in short yes, you have a leak.
I have an application that is being ejected by iPhone OS for "low memory".
I have passed it thru instruments and I see zero leaks, and memory usage is around 640 kb.
The application crashes when I add objects to the screen.
This is how it works. I have a UIImageView based class that is very simple and add a few properties to the objects. This class is used on the created objects.
When the user taps a button a new image of that class is created and added to self.view.
After about 15 objects added, the application is ejected with low memory warning.
Instruments report no significant memory usage. Even after 15 objects added, the ALL ALLOCATIONS entry never goes beyond 660 kb. Each object can be one out of five 120x120 pixels image.
If it is not object allocation or leaks, what can that be? Please tell me what directions should I follow to locate the problem.
Thanks for any help.
The ObjectAlloc instrument does not indicate all memory usage within your application. Views and other visual elements do not show their full size in ObjectAlloc, so you will want to use the Memory Monitor instrument to see the actual memory size of your application at any given time.
Also, just because Instruments does not report leaks does not mean they aren't there. Run your application through the Clang Static Analyzer to take another look for potential memory leaks (via Build | Build and Analyze under Xcode 3.2 or by downloading the standalone tool). Again, even if this passes and you still see continually increasing memory consumption you have a leak somewhere.
You mention using Quartz drawing in your comments. You need to remember that Core Foundation objects used in Quartz also follow a specific memory management model, where everything you create with a function having Create in its name must be released using a matching function like CFRelease(). This may not show up as a leak if you forget this, but it is.
Leaks are not your problem. Over-retention is.
Look at Object Allocations. If that graph just rises and rises, your app will be killed. What make the iPhone especially angry is when you are told to let go of some memory (low memory warning) and no memory is freed. Your code may just be an extreme case of this, but you should free up SOMETHING when you get this message.
I discovered the problem had nothing to do with my code. Every time I use quartz on the iPhone I have this kind of problem.
Quartz has a serious problem that has to be fixed. As far as I detected, it gets chunks of memory to perform drawing and does not release them even if you release all variables and references you use. Even if you put all variables nil.
Quartz is a memory eater and a source for crashes.
Here is a project I've created to demonstrate how Quartz can crash your project. Look for a method inside inside MyClass.m, called imageWithBorderFromImage. This method uses quartz to draw a dashed border around the object. Run the project and click several times in the button. Every time you click, a new object is added to the screen, on top of the previous one. After about 20 clicks the application is ejected by springboard. Before that you will see LOW MEMORY warning on console.
Before telling me that the problem is too many views created, disable the quartz method and see that the application does not crashes anymore. In fact I was able to click 80 times and was still able to continue clicking, but I stopped the app.
Download the project QuartzNightmare here