Inherent UIView leak - iphone

When ran in activity monitor, the real memory usage for a program running the following piece of code will increase endlessly:
CGRect frame = CGRectMake(0,0,0,0);
while(true)
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
UIView *test = [[UIView alloc] initWithFrame:frame];
[test release];
[pool release];
}
What happens is that all objects derived from UIView will leak. Some will leak more than others (UITextView in particular has drawn atention to this problem). The leaks are not actualy discovered in the leaks monitor - their presence is only revealed by the constant increase in memory usage - which eventualy leads to the app being terminated by the OS because of memory exhaustion.
Has anyone noticed this before? For the record, the code was compiled for OS 3.0.

I guess this is an issue with Instruments. Instruments does not work correctly when using with iPhone OS 3.0, e.g. you can't see a stack trace. When using 3.1 in the simulator, this issue disappears (see images). The fact that these do not show up as leaks in Instruments contributes to my assumption.
Of course it could also be that this was indeed an issue with iPhone OS 3.0 and has been fixed in iPhone OS 3.1.
(source: hillrippers.ch)
^^ Instruments with OS 3.0
(source: hillrippers.ch)
^^ Instruments with OS 3.1
This is the code used (in applicationDidFinishLaunching:)
NSUInteger i = 0;
CGRect frame = CGRectMake(0.f, 0.f, 100.f, 50.f);
while (i < 100000) {
UIView *test = [[UIView alloc] initWithFrame:frame];
[test release];
i++;
}

It could be that UIKit is using shared singleton objects when constructing UIView and something allocated by those singletons are not necessarily cleaned by NSAutoreleasePool but is cleaned during standard event loop execution via other means.

I agree this is likely a bug in iPhoneOS. It looks like the CALayer is not getting released. If you force an extra release of the CALayer ([test.layer release], which is an insane thing to do, but "works"), you'll dramatically reduce memory usage, but you'll find that QuartCore is still leaking at least 16 bytes per iteration, which adds up fast in your stress case. I'd open a radar (bugreporter.apple.com).

Related

UIWebView memory issues

I am playing youtube videos on a UIWebView which appears as a modalViewController subview (flip transition). Everything works fine, even though the UIWebView is released, I still receive memory warnings after a few repeated selection of this modalViewController.
I have added my UIWebView programmatically inside ViewDidLoad. Inside viewDidDisappear I check for [UIWebView retainCount] and if greater than 1, perform the following steps:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[self.webView removeFromSuperview];
self.webView.delegate = nil;
self.webView = nil;
NSLog(#"[self.webView retainCount] %d", [self.webView retainCount]);
I am running my code on xCode 3.2.5, iOS 4.2.
Appreciate all you help.
I think you are approaching the memory management problem in the wrong way. Checking the retainCount is a valid debugging technique if you know what you are doing. It is not, however, a memory management tool. In your particular case, if the UIWebView is being displayed it will always have retain count > 1. The superview will have a retain on it thus making the "if" useless.
If the webView property is well defined (i.e. noatomic, retain) the statement:
self.webView = nil;
should release the webView. A common mistake is to initialize the property with:
self.webView = [[UIWebView alloc] init];
This is likely to introduce a leak if the webView is defined as "retain". The correct way is
self.webView = [[[UIWebView alloc] init] autorelease];
If you can't display your controller several times without running out of memory you have a memory leak. Use Instruments (Leaks in particular) to find hte objects what are note being released properly. This is a good tutorial.
Be careful in keeping your retains and releases balanced and check for leaks.
Your problem will be related to this:
Is it possible to prevent an NSURLRequest from caching data or remove cached data following a request?
Scroll down to my answer for an extension of the accepted answer - i had this problem for days and it's now resolved!

iphone app crashes due to Low Memory but works fine in simulator

Dear all, I have a navigation-based app with about 60 UIControllerViews, which is divided into 4 sections.
I have run with the following : 1. Build and analyse : bulid is successful with no complains. 2. Instruments allocation and leaks : no leaks.
However, the app crashed in iPhone or iPad but works fine in simulator. There is no crash reports but I do see LowMemory.log in the crashreporter folder.
I have upgraded my iphone and ipad to 4.2
Does anyone have ideas what could be wrong? I have been reading and troubleshooting for a week.
Is there a need to remove/release the UIControllerViews?
The app crashes simply by navigating between the views.
Thank you for any help.
My app has a root view called contentViewController and users can navigate to 4 quizzes from here.
This is the code I use to return to my root view.
- (void)goHome {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle: #"Warning"
message: #"Proceed?"
delegate: self
cancelButtonTitle:#"Yes"
otherButtonTitles:#"No",nil];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
[[self navigationController] setNavigationBarHidden:NO animated:YES];
if (buttonIndex == 0) {
NSArray * subviews = [self.view subviews];
[subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
self.view = nil;
if (self.contentViewController == nil)
{
ContentViewController *aViewController = [[ContentViewController alloc]
initWithNibName:#"ContentViewController" bundle:[NSBundle mainBundle]];
self.contentViewController = aViewController;
[aViewController release];
}
[self.navigationController pushViewController:self.contentViewController animated:YES];
}
else {
}
}
The simulator isn't going to give you any useful information about memory warnings—your app, running there, effectively has access to all the memory the system's willing to give it. The device is where you need to be testing for memory usage, and if you're getting warnings and crashes, then you need to do some Instruments work to figure out where you can free up some of that memory.
Look at your xcode console. If you are getting a number of low memory warnings, then you need to be allocating and de-allocating your views on the fly because they are taking up too much memory on the device (the simulator isn't quite so memory restricted).
But it could be about a million other things causing your crash. Make sure you're doing a debug build (breakpoints on) so the debugger will kick in and hopefully you can see where on the stack your crash is occurring.
You have some good suggestions already. However I'd suggest spending a lot of time reviewing XCode's debugging tools documentation. This so you have a basic understanding of what they are capable of and how to use them. Follow that up with some reading on iOS memory management, auto release pools and the like.
For your app you need to realize that there is no swap space on iOS devices. So you are forced to manage memory to an extent that you mat not have to on other platforms. Generally that means you don't want to keep to much view data in memory if it can be avoided.
In the case of the current iPad there may only be about 110MB of RAM available to the app. Specific numbers probably are iOS version dependent. In any event you need to get an idea as to how large the data structures (in memory) are for your various views. 60 different views could be considered a lot depending upon memory usage, if you don't manage it correctly you are likely to run out very quickly. This not like programming in Java or other garbage collected language.
Lastly; even though this sounds like a memory management issue it could always be something else. If you still have trouble you will need to post code. Right now it is really guess work on our part. Just remember you do not have VM and there is no garbage collection.
You are using up memory, always remember if you allocate memory you must release it, in some cases you can use autorelease so you dont forget to release it after the void dealloc method before end.

Program received signal: “0”. warning: check_safe_call: could not restore current frame

I am getting this error on my application
Program received signal: “0”.
warning: check_safe_call: could not restore current frame
I had also enabled Zombie but its not showing any info about memory corruption in one particular case and showing above error.
How to resolve this error?
Any help will be appreciated.
try rebooting the iphone to clears it's memory and restart your dev machine, build clean all targets see if that helps
Could you please give some more information? Does this error occure when starting the app out of XCode? On the iPhone or in the simulator? Does the app show anything or does it crash on startup?
Perhaps you are having to much memory allocated and the iPhone OS does force quit your application. Does it happen in the simulator?
There also seem to be a relationship between the Expression window and this error Link to forum thread
I ran into this when rapidly changing images in an UIImageview.
Using object allocation tool from instruments, I saw that the memory was increasing rapidly until it cracked. I double checked by implementing :
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
in my main.
This was, in my case at least , a memory management problem.
I was using [UIImage image Named:] which is an autoreleased UIImage. That cannot be released by the user and it caused the specified problem. I fixed this by implementing allocation and release programatically on all of the objects in question.
Sample code where I update an UIImageView's image:
-(void) updateImage{
CGRect rect=CGRectMake(0, 0, 320, uiviewsimage.frame.origin.y);
NSObject *img2=CGImageCreateWithImageInRect(uiviewsimage.CGImage, rect);
UIImage *newImage = [[UIImage alloc] initWithCGImage:img2];
[img2 release];
[myImageView setFrame:rect];
[myImageView setImage:newImage];
[newImage release];
}
Hope this helps someone.

iPhone CGRectMake memory consuption

On iPhone.. Why would code such as this cause memory leak? after 2 minutes the net bytes have doubled.
All I'm doing is moving a ball round the screen with an NSTimer calling the below method.
Any ideas?
- (void)nextFrame:(NSNotification *)notification {
ballInstance.frame = CGRectMake(value, 0, 320, 480);
}
here is the 'full' code, new project, still behaves the same. It moves a jpg accross the screen, and as it does memory is massively consumed. If I remove the '++' from 'value' memory is fine. (in otherwords have a static graphic) So.... is the image being cached is the question?
If so how can i stop it reaching astronomical sizes?
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window makeKeyAndVisible];
NSTimer * nSTimer =[NSTimer scheduledTimerWithTimeInterval: .02
target: self
selector: #selector(tick)
userInfo: nil
repeats: YES];
value =0;
}
- (void)tick {
NSLog(#"tick");
myOutlet1.frame = CGRectMake(value++, 0, 320, 480);
}
The posted code has no leak. The problem is elsewhere.
If you know that there's a leak inside of nextFrame:, it has to be in -[Ball setFrame:] because it is the only message sent in this method.
The leak is not in the code you show, especially if frame is a #synthesized property. You either need to show more code, or spend some quality time with Instruments to figure out what is being leaked and where it is being allocated.
According to Apple:
This is a bug in iPhone OS 3.0. The allocator for the graphics system
is reporting realloc events as malloc events, so ObjectAlloc tallies
these as new objects that are almost never being freed. I'm not
certain why you might not see it when you add the Leaks tool, but
neither tool would show a true leak for this.
Though I'm still none the wiser as to how to remedy it.
I've posted a complete sample application that seems to more or less match your "new project" example above. Can you take a look at it and see if this gives you any ideas? I've run it on the simulator and on the device w/ no leak.
http://static.fatmixx.com/MemTestApp.zip
It really does look like there is NO leak here. I'm building against iPhoneOS 3.1 - Debug.
Sujal

Memory leak issue with UIImagePickerController

I'm getting memory leak with UIImagePickerController class.
Here's how I'm using it:
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
[picker release];
To remove the picker i call [picker dismissModalViewControllerAnimated:YES]; in didFinishPickingImage and imagePickerControllerDidCancel.
--
Instruments show around 160bytes leaking as a result of this instruction:
+[UIImagePickerController _loadPhotoLibraryIfNecessary]
Apparently this issue has and is disturbing many people, and solution
to avoid this problem is to build a
singleton class dedicated for picking
images from library or capturing using
device's build in camera.
Anyone want to add something?
As the author of one of the first articles about the necessity to use a singleton, the motivation was to prevent a crash on the 7/8th image capture, not because of any particular worry about the leak. 160 bytes is annoying, but not a major problem, and therefore not worth worrying about (because it can't be fixed by developers).
Have you tried deleting the delegate line? I’ve had similar problems with AVAudioPlayer when delegating to self. (Even though the accessor says assign in both cases.) If the leak goes away with the delegation, you can delegate to a different object.
I was having a memory alloc leak which I found in Instruments.
All I was doing was opening and closing the image picker (open/cancel) and using Apple code, my code and other people's code.
All were showing the allocation going up and up each time, as if the picker was not being released.
If you tried to release it, it would crash (over released).
Then I found a really helpful web page which basically stated:
"This doesn't happen when testing on the device"
So I switched from the simulator and ran the tests on the device.
Lo & behold there was no allocation increase and it behaved normally.
This however is totally evil and now we can place no trust in the simulator to do a reliable job. Whether this is pertinent to your specific problem or not, I took you up on anything else to add, and my thing to add is don't test memory on the simulator!
The reason maybe that you forget to release image. Because each time you write
UIImageView.image = image_a;
Then , image_a will get retained once.
Until you let UIImageView.image = nil, when image_a can be release finally.
I resolved my problem in this way.
If you see memory leaks several GeneralBlock and SegmentMachO by using UIImagePickerController,
Try by adding CoreLocation framework and MapKit framework to your project. I don't see anymore memory leaks in the instrument tool leak checking. I don't know how UIImagePickerController related to these frameworks. I am not sure it is good solution or not. "adding frameworks without using or necessary".
I have also got the memory leak by using UIImagePickerController. That memory leak happen even in the sample code "PhotoLocation" and "iPhoneCoreDataRecipes" downloaded from developer.apple.com. I also checked by adding these frameworks to those downloaded sample code. There is no memory leaks anymore.