Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

vegashacker

macrumors newbie
Original poster
Apr 20, 2008
14
2
I'm experiencing a consistent increase in the net number of objects (as determined by Instruments) when I try to do a simple asynchronous url request. Note that I do not see a leak detected visually, but when I look at the number in the "# Net" column, I see the number increasing each time I make a call to a server. I stripped out everything that I could to make the simplest example possible:

In applicationDidFinishLaunching, add
Code:
	posty = [[Post alloc] init];

Add an action method linked up to a simple button in the app:
Code:
-(IBAction) clicky:(id)sender {
	[posty post];
}

Post.m looks like this:
Code:
-(void) post {
	NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];
	[theData release];
	theData = nil;
	theData = [[NSMutableData data] retain];
	[[NSURLConnection alloc] initWithRequest:req delegate:self];	
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];
}

To test, I click the button (slowly, to ensure a full request has finished) a few times until the allocations in Instruments seem to stabilize. After that point, with each click the # net allocs increases by by a few.

Any ideas on what's causing this? I tried to follow the Apple Doc's example closely (and make it even more simple for the purposes of my debugging and this post).

Thanks,
Rob
 
My opinion

I am no expert at objective c memory manangement as I still find some aspects of it confusing. I beleive your problem is in the post method. You are doing the following on the last line of the method.

Code:
[[NSURLConnection alloc] initWithRequest:req delegate:self];

You should be doing a release on this afterwards before the post method ends.

I.E.
Code:
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:req delegate:self];
[connection release];

So for each post method you would be leaking one NSURLConnection. In general each time you call an alloc, that method is responsible for doing a release on it at some point. In this case since it is a local variable, you need to decide what you are going to do with it (release, autorelease) before the method ends. If others are going to use it (the initWithRequest method for example) they are responsible for doing a retain on it.

It looks like you are doing a release at the end after the connection did finish loading, but are you guaranteed that it is the same object you initially created? I may have been copied at some point and you are seeing a different instance of the NSURLConnection object.

From you code sample I do not see any case where you would be leaking any NSURLRequest objects

As a side note, I find the memory management in objective c to be the most confusing of other languages that I have seen. I really wish the garbage collection feature would make its way into the iPhone.

Hope this helps
 
Thanks for the reply, but I don't think this is the problem. See this Apple document (http://developer.apple.com/document...LoadingSystem/Tasks/UsingNSURLConnection.html). In it, they alloc the object and then release it in another method. The reason is that this is an asynchronous request. If you released the connection right after you created it, it wouldn't have time to finish (and in fact, the app crashes if you try this). It may be that you are right about the duplication of the object, but then how am I supposed to do it?

I'm suspecting a bug, but I'd like someone else to independently verify that.
 
So what are the objects that are being allocated that cause your memory to increase? You can see the exact stack trace for each allocation in the timeline.

I can tell you that NSURLConnection does a lot of things. It creates a background thread that I think doesn't go away. I haven't looked closely at its allocations but this might not be a problem.
 
Any solution..

Thanks for the reply, but I don't think this is the problem. See this Apple document (http://developer.apple.com/document...LoadingSystem/Tasks/UsingNSURLConnection.html). In it, they alloc the object and then release it in another method. The reason is that this is an asynchronous request. If you released the connection right after you created it, it wouldn't have time to finish (and in fact, the app crashes if you try this). It may be that you are right about the duplication of the object, but then how am I supposed to do it?

I'm suspecting a bug, but I'd like someone else to independently verify that.

Hi,

I am also suffering with same problem. My application also consists of multiple http connection using a timer. This also shows the increase in #Net allocations and after some time the Histogram turns to pink and finally the app crashes with no memory leaks shown at all. Please help me if u found any solution...
 
What I did

In my code, I found that if I released the NSURLConnection object in the connectionDidFinishLoading delegate method, it showed up as a leak in Instruments.

If I release it after a delay (outside of the connectionDidFinishLoading method), the leak went away.

Or, you could just use [NSURLConnection connectionWithRequest:delegate:] instead of alloc/initWithRequest and don't worry about releasing it at all since it will be autoreleased. This doesn't leak either.
 
Cache Policy

In my code, I found that if I released the NSURLConnection object in the connectionDidFinishLoading delegate method, it showed up as a leak in Instruments.

If I release it after a delay (outside of the connectionDidFinishLoading method), the leak went away.

Or, you could just use [NSURLConnection connectionWithRequest:delegate:] instead of alloc/initWithRequest and don't worry about releasing it at all since it will be autoreleased. This doesn't leak either.

I tried the above options ,but stil I am suffering with the problem.
when i am starting my connection for every 15 secs using timer , the memory grows and grows. Leak Instrument showing no leaks, but showing the following are the Responsible callers, for the memory increment..

1) sqlite3pageracquire
2) ProcessCacheTasks(_CFUrlCache*)

Thank u.
 
nsurlcache

I got the problem of #Net keeps on increasing solved by using the following code in application did finish loading function.:

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];

I think it cleans up the cache .

But there is one more issue left behind, that is of #Allocation Histogram is turning from BLUE to Red as #Overall Allocation value keeps on increasing.

And the Application gets crashed after a some time.

Please help if any had faced this issued.
 
Anyone found a soloution.

Im struggling with the same problem as above.
Been searching google like mad, can anyone tell me how to get rid of this memory leak?

Edit:
I now declared theConnection like NSURLConnection *theConnection; in the interface of the class.
I then say:
self.theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

In the fail, receivedata and dealloc I have:
self.theConnection = nil;

this gets rid of the analyse warning, so I hope that is the way to do it.
 
Last edited:
BlueDevelop, unles you have the property declared with assign keyword, this is a leak:

Code:
self.theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

Use temp variable or autorelease.
 
I have @property(nonatomic, assign) NSURLConnection *theConnection;

I tried using NSURLConnection *connection and releasing that.
And I tried autorelease.

With NSURLConnection *connection the analyser complains about leak.
And with autorelease it is released before the actually data has been fetched.
 
Last edited:
Clear cache

I had the same problem, at the end of your request just add this line:
Code:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
 
Last edited by a moderator:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.