Any suggestions on how to work around this UITableView Leak?
Here's a link to a very basic test project that produces the problem:
http://www.maani.us/temp/Test.zip
To reproduce the leak:
Run the project with the "Leaks" performance tool.
In the table view, click '4' in the right-side Index to jump to section 4.
Scroll up a bit to display a couple of cells from section 3.
Wait for a few seconds. This generates a leak in the instrument.
I tested this both with version 4.2 and 4.3, both with the simulator and a device. All tests produce the leak.
Thank you for you help.
Are you testing this in the simulator or on the device? There are some known leaks with UITableViewControllers in the simulators that do not happen on hardware.
I ran this myself in my the simulator and the only leaks I am getting are for NSIndexPAth and generic 16 byte blocks, both of which are discussed on the internet as being leaked only on the simulator. You can also look at the leaks and see they are created and only accessed within the foundation framework. Therefore, it definitely seems to be a problem with the framework itself. One possible fix for this is to use a UIViewController and setup the UITableView yourself.
The test project above contains only the minimal code necessary to build a UITable and confirm that the leak is in the foundation framework (NSIndexPAth).
Yes, the leak happens on devices too.
The original code used a UIViewController that displayed a UITableView. That too produced a leak. I removed UIViewController to narrow down the problem and confirm that the leak still happens without too.
The only thing that removed the problem is removing the UITable section Index (sectionIndexTitlesForTableView:tableView), which is not a possible option in the final App.
Related
First of all I want to say that I'm I aware that my question is probably way too vague to answer and may be closed/down-voted. I just hope for some inspiring brain-storming on possible solutions.
Here's the story:
My app was crashing on iPad 2, but not on iPad 1. I've fixed the crash related to unarchiving nib and now I have a very strange problem - my universal app still runs without any problems on 1st gen iPad with iOS 4.2.1 and 4.3.3, but not on (some/all?) iPads 2 with 4.3.3. Unfortunately I don't have an access to iPad 2 with iOS < 4.3.3 to test further and narrow down the problem.
My app has it's main screen displayed by using presentModalViewController. My modal VC is MGSplitViewController (it mimics native UISplitViewController and enhances its functionality). When my VC is presented, only "root view" is displayed and remaining part of screen for "detail view" is just black and empty however the controller is loaded and active (debug logs are printed etc.).
So on iPad 2 I have access to, it fails to display detail view properly, however I've heard from one user that it's fine on his iPad 2 (both iOS 4.3.3). App also works ok on iPhone/iPod regardless iOS version, so I assume it's related only to iPad code of my universal app.
I believe it may be more general issue with displaying views. I've tried to read view property of my detail view, which should force view to be displayed, but it didn't help. It may also be related to IB stuff (the initial nib unarchiving crash only on iPad 2??), but I think everything is wired ok in IB...
Anyone has a slightest idea how to investigate this problem?
EDIT: BTW: My iPad 2 is giving me hard time as it drops Wi-Fi connection very often. Other people are also reporting this kind of "feature". Can it be that it's just something wrong with my iPad 2?
EDIT2: the app is also not correctly displayed on iOS 3.2, 4.2 and 4.3.3 Simulator (via XCode 4), but gets displayed correctly on iOS 3.2, 4.2 Simulator via Xcode 3. Strange, isn't it?
Anyone has a slightest idea how to investigate this problem?
If you'll allow a somewhat vague answer to a somewhat vague question, then yes, I do have an idea.
To approach problems like this in general, bisection of the problem field is a great way to go forward:
You identify the general problem area. Could it be presentModalViewController in your case?
Then about halfway through the code in question, you set a breakpoint/write a message to a log file/play a sound/send a mail/tweet/whatever it takes to verify that your code has come that far without a crash.
Run it and see if your message has been produced.
If it has been produced, the problem is not in the first half, so it must be in the second half (a log message at the end of the identified problem area is useful, too, just to make sure that the crash actually happens before that).
On the other hand, if there is no trace of your log message, then the crash must occur in the first half, and you can rule out the second half of your code for this particular problem.
Now you repeat the algorithm by setting your breakpoint/log message about halfway into the culprit half you just identified.
Repeat until you find the problem. It won't take many iterations.
Of course, the crash may be due to some variable stored at a previous step or in another method, but now you know where to look.
Initially the app was crashing due to unarchiving the nib. I don't recall the exact crash output, but it was quite strange for me that same nib was properly unarchived on iPad 1 with same OS version, so I suspected that the problem lies in xib file... I've recreated the xib from scratch routing everything carefully and - bam! - it started working on both iPad 1 and iPad 2! How come some nibs aren't unarchived in a same way on same OS running different HW???
I have a working iPhone app using SDK 4.0. It shows no leaks in the 'Instruments' tool, and I am fairly convinced that the code does not have any memory leaks.
I then tried to add iAds to the app, and it started showing memory leaks. In order to nail down the problem, I removed all additional code.
All that is left is an added AdBannerView to the .xib file (without doing a single modification to the working version of the code without iAds). This shows memory leaks.
Every time the view loads, the 'Instruments' tool shows 5 leaked blocks of 16 bytes each, with the Responsible Library 'Foundation', and Responsible frame
[NSCFString copywithZone:]
Further running the app gives me leaks from the Responsible library 'iAd' (2 leaks of 48 bytes each), and the responsible frame:
[AdBrandingFrame initWithFrame:]
Further, I also get 48 byte leaks with the responsible library 'UIKit' and responsible frame
-[UIView _createLayerWithFrame:]
Since there is absolutely no addition to my working non-leaking code, except an added AdBannerView to the .xib file, I wonder if it is Apple's code that causes the leak. Although the leak is relatively small, I would like to iron it out. I understand that there is a possibility that a leak shows up even though there may not be one (the pointers might still be held by the OS in some way that Leaks does not know about - It would be great to know if this is the case).
So I had two questions:
1) Is there any chance the problem is actually my code, and the leak for some reason only shows up after adding AdBannerView? If there is such a possibility, I would run another thorough code test.
2) If this is a problem with Apple's code and any of you have encountered this, are there any workarounds you have found?
Any help would be greatly appreciated. Thanks!
I just had the same issue. I think this has been fixed in IOS 4.1
When I test in 4.0 I got a couple leaks "NSCFString copyWithZone"
When testing in 4.1 all is good.
See the screenshot below, this is the only leak the Leaks Instrument finds in my app. Seems odd that main is leaking since it's out-of-the-box. Is this common?
This usually indicates that the leak is occurring somewhere before the app delegate loads. Check any added resources like compiled libraries.
Drag this code source or your app delegate source into Instruments and it might show you the call stack so you can track it down.
Edit01:
See IPHONE: Analyzing leaks with instruments for an example of how to view source in Instruments.
i'm only create an project with a Utility Application template.
This template has a native memory leak when i push "info button" to
flip the view.
Anyone know how can i fix this leak ???
I just make an new project from this template,
i don't add new objects.
That might be a leak or it might not be a leak. If you were to add the backtrace of the allocation, that would be helpful.
More likely than not, it isn't a leak, but some bookkeeping information that is being stashed away by dyld that leaks/Instruments loses track of.
Given that it is 128 bytes and I'm guessing there is only one of them, I would encourage you to file a bug via http://bugreport.apple.com and then forget about it for now as, in the unlikely case that it really is a leak, you will be equally as unlikely to be able to fix it from within your application.
Hope this helps.
From: http://www.cocos2d-iphone.org/forum/topic/2460
"The simulator has bugs related to singletons and llvm stuff that are incorrectly reported by Instruments. Always check your leaks on the device itself."
Got the leak doing this:
XCode 3.2--
File, New Project, Navigation-based Application
Give it a name
Build It
Run With Performance Tools -> Leaks
When Instruments comes up, click on Leaks (you might have to click the little icon at the bottom that looks like four boxes within a box)
About 7 seconds after running you should see the leak:
-- Malloc 128 Bytes, some Address, 128 Bytes, CoreGraphics, open_handle_to_dylib_path
I traced it to this code in the AppDelegate:
//APPLE CODE
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
I broke out the navigationController (did a separate alloc and release) and COMMENTED OUT the addSubview: action - there was no leak - and, obviously, the screen was blank.
It wasn't until I attempted addSubview that the leak occurred. Since there are numerous ways to add a subview, I tried those. Each resulted in the leak or a blank screen.
I tried it on a real ipod touch. No leak was reported.
Probably just a simulator thing ...
Leaks has flagged open_handle_to_dylib_path in CoreGraphics for me as well; there is definitely something flagged here. Since it is merely 256 bytes at its heaviest, I fired off a bug report to Apple and called it done. You can then set a rule in Leaks' configuration to ignore the report.
As bbum pointed out, there might be serious voodoo at work. I seriously doubt Apple would let leaky frameworks go through QA -- especially since it's so easy to reproduce.
This must be a bug. It appears in Apple's own example, PageControl, found here:
http://developer.apple.com/iphone/library/samplecode/PageControl/index.html#//apple_ref/doc/uid/DTS40007795
In the current SDK utility template is no leak. How did you get the impression there's a leak in the template? It's just allocating memory which is needed for the views.
A leak is memory to which no pointers exist and which cannot be freed any more.
I had the same problem, but was able to understand why it happened. And I have given a brief info regarding this problem in this article
Might be useful for you.
I have an app that has a tabBar Controller and a navBar Controller. It has ~8 views (a variety of web, table, standard, mail, address etc.), some created using IB some created using XCode to make the table views. I've ran the memory leak tester and it doesn't have memory leaks. It can crash at anytime on any of the views, If I flip back and forth between views and use some of the functions it closes the app.
I assume that either I am running 1) out of memory or 2) not releasing views correctly, which causes the app to close. The app is simple so I don't know how I could be out of memory and I've reviewed the code to the best of my ability for releasing the objects correctly.
So Here is my list of questions:
1) What and How to use some of the other debugging tools (or tell me what tools/files I should be looking for using)? I would like to narrow down the problem to its source.
2) What is the best practice for releasing these views? How?
3) How much memory do normal apps use? Is there a number that I should stay around? How do I verify that in the simulator? the Allocation tool?
Feel free to point me to apple docs or other stackoverflow questions that can help me.
UPDATE: It appears to only be crashing one view is used, which has a table view with custom cells... The cell are populated from a plist file... this view worked fine a few days ago, I notice that some cells do not have data from the plist file... it could be a plist file problem with not storing proper data. I'll continue to work on it.
UPDATE #2: I went back to older rev of my files, to when this particular tableView worked just fine (pre 3.0) and guess what it works just fine, I change the simulator to 3.0 with this rev of the app and bam crash on this tableView shows up. Thanks for the help so far, I'll try somethings mentioned below and let you know what I find. If you have some tips on why a tableView w/custom cells from 2.2.1 to 3.0 would start crashing, I'll take them. If I can't get anywhere I'll post the code soon. BTW, I mis-spoke above, I thought it wasn't crashing in the simulator... I was wrong it is.
Solution: thanks for the troubleshooting tips the fix was quite simple, but it's odd it didn't crash in 2.2.1... it should have crashed a long time ago for the problem, I was releasing an object one to many times in my custom cell... duh.
On the first and second generation phone's you really don't want to be going over about 20 megs of real memory usage - once you get over that you are at risk of being killed by springboard.
One of the big culprits I've seen is autoreleased memory, since the autorelease pool can hold onto memory a lot longer than you would really like - if you are using a lot of autoreleased objects that can be a potential problem. You can improve this by doing more explicit retain/release where possible and by creating local autorelease pools manually and releasing them after doing a more intensive operation with a lot of autoreleased objects.
The most effective way to keep track of real memory usage I've found so far is running a debug build on a test phone and running with Activity Monitor. That will give you a clear idea of how much memory is getting taken and held onto by your app. As well as how much is being used when it crashes on you.
You can run with Activity Monitor in Xcode on the Run menu -> Start With Performance Tool -> Activity Monitor.
One other very useful tool is the CLang Static Analyzer that you can run against your code base and can give some very helpful memory management information. As mentioned here.
One thing I would try is putting some debug messages into your didReceiveMemoryWarning method(s). That way, if you are running out of memory, you'll at least have some warning.