iPhone CGRectMake memory consuption - iphone

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

Related

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.

Received memory warning. Level=1 when showing a UIImagePickerController

This is driving me crazy!!!
I'm getting a "Received memory warning. Level=1" whenever I attempt to show a UIImagePickerController with a sourceType = UIImagePickerControllerSourceTypeCamera.
Here is the code from my viewDidLoad where I set things up:
- (void)viewDidLoad {
[super viewDidLoad];
// Set card table green felt background
self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:#"green_felt_bg.jpg"]];
// Init UIImagePickerController
// Instantiate a UIImagePickerController for use throughout app and set delegate
self.playerImagePicker = [[UIImagePickerController alloc] init];
self.playerImagePicker.delegate = self;
self.playerImagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
And here is how I present it modally ..
- (IBAction) addPlayers: (id)sender{
[self presentModalViewController:self.playerImagePicker animated:YES];
}
The result ... UIImagePicker starts to show and then boom ... I get the memory warning ... EVERY TIME! Interestingly enough, if I switch to sourceType = UIImagePickerControllerSourceTypePhotoLibrary ... everything works fine.
What in the heck am I missing or doing wrong? All I want to do is show the camera, take and save a picture.
FYI - I'm testing on my 3GS device.
Thanks to anyone who can help :)
This is very common. As long as you handle the memory warning without crashing and have enough space to keep going, don't let it drive you crazy.
It is not about how much memory your app has used, because it will probably happen even when you write a very simple app which have only one view with one button, clicking the button and then open camera.
I have tested on iPhone 3GS, iPad 2 and iPod touch 3G. It only happened in iPhone 3GS.
I found it will not happen anymore if you restart you device before you execute you app.
Another real solution is to comment the code, [super didReceiveMemoryWarning], in your viewController.
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
After lots of test on iPhone 3GS with iOS 4.3.2, I found the logic might like that:
-> Open as much as app running on background
-> Presenting a imagePicker of UIImagePickerController, clicking "Back" or "Save" from imagePicker
-> ApplicationDelegate's method, applicationDidReceiveMemoryWarning:(UIApplication *)application, will be invoked
-> Then ViewController's method, didReceiveMemoryWarning:, will be invoked
-> Then viewDidUnload
-> Then viewDidLoad
Then you could find some views have been released and the current view has been pointed to a unexpected one.
By default, [super didReceiveMemoryWarning] will run when ViewController's didReceiveMemoryWarning method is invoked. Commenting it, and viewDidUnload: and viewDidLoad: methods will not be invoked. It means the mem warning has been totally ignored. That's what we expected.
Now after I upgraded to 4.0 it happens to my app too - before in 3.1 there were no warnings.
Actually as you said before, there should be no issue. However, this causes the view that comes after it to load again and viewDidLoad is being called. This messes up my app, since I initialize the view in viewDidLoad - now it gets initialized all over again - even though it shouldn't.
Just as a comment, this might also happen to many other apps that rely on loading the view only once!
It did happen in my app Did I Do That on iOS 4.0 too. It was not consistent, but the most common cause was creating a UIImagePickerController instance and navigating to some large photo stored in one of the albums.
Fixed by persisting state in the didReceiveMemoryWarning method, and loading from state in the viewDidLoad method. One caveat is to remember to clear the state-persisted file in the correct point for your application. For me it was leaving the relevant UIViewController under normal circumstances.
I'm getting the memory warning when opening a UIImagePickerController as well. I'm on 4.01 as well.
But in addition, the UIImagePickerController is running the close shutter animation and stalling there, with the closed shutter on screen.
It seems like the UIImagePickerController's behavior on memory warnings is to close itself.
I could dismiss the UIImagePickerController from the parent ViewController in the didReceiveMemoryWarning method, but that would make for a terrible user experience.
Has anyone seen this problem?
Is there a way to handle the memory warning so that the UIImagePickerController doesn't shut itself down?
I have been struggling with the same problem for some days now. However, resetting my iPhone 4 (clearing out memory) solves the problem so it's not really an app problem.
It appears that a level 1 or 2 memory warning triggers the UIimgPickerController delegate to offload itself. The same happens in my app with the delegate of the delegate (yes it can). After the memory warning however, it will load the delegate (and it's delegate) again causing the viewDidLoad to execute any code that's in there.
I am not sure this happens only while using the UIimgPickerController because testing all that is very time consuming.
I could write some extra code to prevent the code in viewDidLoad en viewWillAppear from execuring while showing the UIimgPickerController but that's not classy, right?
Here's food for thought: it could be
that you are running out of memory
because you are testing your app. With
some memoryleaks it is very well
possible that you are working towards
this problem every time you debug.
The UIImagePickerControllerDelegate is a memory hog because you are capturing high memory assets, be that an image or video. So from the start be sure to specify the medium capture settings, as a start point, reduce this if you don't need the quality:
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.videoQuality=UIImagePickerControllerQualityTypeMedium;
Then after capturing and using these assets. Remove any temp files from the applications temp folder. Could be an extra obsessive step but its a good habit:
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:[lastCapturedFile substringFromIndex:7] ]) {
NSError *error;
// Attempt to delete the folder containing globalDel.videoPath
if ([fileManager removeItemAtPath:[lastCapturedFile substringFromIndex:7] error:&error] != YES) {
NSLog(#"Unable to delete recorded file: %#", [error localizedDescription]);
} else {
NSLog(#"deleted file");
}
}
With above it is clearing the file that was created by the delegate. In some instances if you are transcoding or creating you own assets delete the folder with that file. Note above I am removing the 'file://' part of the url string as the file manager doesn't like it:
[lastCapturedFile substringFromIndex:7]
Other things to consider are covered in the various documentation for what you are doing with that asset - transcoding, image size reduction and more. Beware that any transcoding using the AVFoundation will crash if the UIImagePickerViewController is displaying.

How UIWindow#addSubview can make memory leak?

I started to learn using Instrument, but I cannot figure it out.
After I start my application, the UI shows up, I do nothing and after few seconds I can see memory leak detected:
When I have a look at the second leak I can see the following stack:
When I double click on the cell related to my code I can see that it is pointing to the following line of code:
[window addSubview:newPostUIViewController.view];
from the method:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
//creating view controller
newPostUIViewController = [[NewPostUIViewController alloc] initWithNibName:#"NewPostView" bundle:nil];
newPostUIViewController.title = #"Post it!";
[window addSubview:newPostUIViewController.view];
// Override point for customization after application launch
[window makeKeyAndVisible];
}
I wonder, how this can be a reason of a leak? I release newPostUIViewController in the dealloc method of PostItAppDelegate class.
Any ideas how this could be explained?
You did not provide an autorelease or release to balance your init. Just in case you haven't read through it already, have a look at the memory management guide is a great help.
Looking at link text allows to say that this is Simulator problem, not the code problem.

Inherent UIView leak

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).

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.