iPhone memory leak issue in ZipArchive lib - iphone

I'm gratefully using the ZipArchive library but it seems there is a memory leak. I don't know how to fix this - it's written in C and I'm unfamiliar with it. My question is - is it possible to autorelease the line s=(unz_s*)ALLOC(sizeof(unz_s)); like you would in Objective-C in this scenario?
extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
const char *path;
zlib_filefunc_def* pzlib_filefunc_def;
{
// ...
s=(unz_s*)ALLOC(sizeof(unz_s));
*s=us;
unzGoToFirstFile((unzFile)s);
return (unzFile)s;
}
Here is a screen grab of the location of the leak for clarity:
http://ziparchive.googlecode.com/issues/attachment?aid=-5463964192517894688&name=Screen+shot+2010-08-20+at+8.12.58+PM.png&token=8c66aa58a4826b99ba157903fbae83bb&inline=1
Can anybody could shed some light on how I might fix this? Thanks.

i have faced the same problem and Solved by reading some of the blogs . it seems to simple
close your ZipArchive Object before relesing Objectits look like [ZipObj UnzipCloseFile];

No, you cannot autorelease it. Autoreleasing is only available for Objective-C objects. So you have 2 options:
Free the memory yourself using free().
Wrap the s thing into an NSData using dataWithBytesNoCopy:length:, which will take ownership of the allocated data and free it when the NSData object is deallocated.
Option 2 would look something like this:
unz_s * s = unzOpen2(...);
NSData * boxedS = [NSData dataWithBytesNoCopy:s length:sizeof(unz_s)];
Then when boxedS gets destroyed, it will free s as well.

Related

Is <non-object> kind of memory link or abandoned memory?

I'm using instruments to tracking memory usage. Heapshot Analysis is awesome, but I also found some "non-object". what's this? kind of abandoned memory or something else ? How to solve this ?
Another Question may relate,
I used to use
[myObj release], myObj = nil;
myObj = [[MyObj alloc] init];
to release object and create a new one. (myObj = nil, just for avoid crash)
Some guy said, It may waste memory performance. Is he right?
I want to know some details.
Very appreciate for your help.
Your question has an answer here:
What does <non-object> in Allocation "heapshots" mean?
For the memory management there's absolutely nothing wrong in your code. myObj = nil is pointless because you're allocating a new object in the line after it.

How can I keep memory usage low with a lot of NSStrings, or how do I release NSStrings?

I am working on an app that imports a (very) large csv file into Core Data for catching purposes. The process goes something like this:
Parse the file line-by-line into an NSMutableArray full of NSStrings
After X number of lines, import the array into Core Data (this involves manipulating and in some cases creating new NSStrings)
[NSMutableArray removeAllObjects];
Rinse and repeat
At first glance it looks like the memory should be freed up at the conclusion of each cycle. With large files, however, I am finding that the app crashes after signaling a couple low memory warnings. Running the leaks tool tells me that most of the memory is being used up by CFString objects, which I understand are related to NSString objects (although I don't know how)
I understand that NSString are reused whenever possible, and that they don't act quite the same as other objects where memory is concerned, although I don't understand any of the details. How can I reclaim the memory that my NSString objects are using?
Running the leaks tool tells me that most of the memory is being used up by CFString objects, which I understand are related to NSString objects (although I don't know how)
NSString is actually a class cluster. Although you think you are working with NSStrings, you are almost certainly really working with one of its subclasses. The Cocoa framework chooses which subclass to use depending on circumstances.
CFString is actually not really an NSString at all, it is the pure C string object used by Core Foundation. However, you'll find it is "toll free bridged" to NSString. This means that, to Cocoa, it looks like an NSString. The reason you are seeing lots of CFString usage is because whatever Cocoa API you are using to obtain these strings ultimately performs its work in Core Foundation.
Anyway, all that is irrelevant to your problem except for the fact, that lots of CFStrings more or less means the same as lots of NSStrings. What you need to reduce your memory footprint is nested autorelease pools as Girish has already said. As a first step, modify your algorithm like this:
Create a new autorelease pool.
Parse the file line-by-line into an NSMutableArray full of NSStrings
After X number of lines, import the array into Core Data (this involves manipulating and in some cases creating new NSStrings)
[NSMutableArray removeAllObjects];
drain the autorelease pool
Rinse and repeat (start at 0)
If this doesn't help, or only helps a bit, consider bracketing just the parsing with an autorelease pool.
I am assuming that you don't have memory leak.
If you are using too much autoreleased object this can happen
You try following
Create nested auto release pools --- some time happen that you have some long running loops where auto release object get accumulated. -- so add custom auto release pool to release the auto release object when you required.
Don't use autorelease object in the parsing cycle --- do manual object allocation and release once your work is done.
You can't sure that the memory is consumed by NSStrings only. I suggest you check it thoroughly. Try to go for "Build and Analyze" it will help you to find out leaks.
While using NSString object, instead of going for autoreleased objects like
[NSString stringWithFormat#""];
create your own object and release it as soon as you done with it.
NSString * string = [[NSString alloc]initWithFormat:#""];
//use string object
[string release];
this way you can be sure, that you releasing the string there itself.
or create an Autorelease pool
NSAutoReleasePool * pool = [[NSAutoReleasePool alloc]init];
// do you coding, creation of objects, releasing them, whatever...
[pool drain]; or [pool release];
Also have a look at these memory management tips

Nasty NSPropertyListSerialization Leak

NSString *anError = nil;
id plist;
plist = [NSPropertyListSerialization propertyListFromData:rawCourseArray mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&anError];
if (anError != nil){
[anError release];
}
The above code causes a memory leak every time I call it. I am releasing the error but still there is a leak. I haven't seen any resolution to this issue. I posted this already and most respond that this is not a leak. But see here in the leak performance tool:
I need this fixed because eventually my app crashes. Any ideas? Many thanks
I had the same problem. Used propertyListWithData:options:format:error: with same result. Used NSDictionary initWithContentsOfFile with same result:
Leaked Object # Address Size Responsible Library Responsible Frame
NSCFNumber,19 < multiple > 304 Bytes MediaToolbox FigRemote_CreatePropertyListFromBinaryPListData
FWIW - I only have dictionaries and arrays and strings in the pList, no numbers.
The issue is not the error object (or string in your method). The issue is not plist above, since it should be autorelease. In the end, I gave up and reimplemented using JSON and:
http://stig.github.com/json-framework/api/index.html
==> no more leak.
Best,
Fred
I've had the same problem before.
Basically this is because your error variable got released without initiating it. So what you can do is try to init your NSString *error to an empty string before releasing it. Or not releasing it at all.

Memory leaks caused due to CoreFoundation Framework

I am developing an iPhone application which mainly makes use of the Address Book and database. After fetching about 3000 contacts from the address book, I am attaching string tags to the contacts (5 for each). I am saving my tags in the database.
For Load testing purpose i have added 10,000 tags to the App. But during the load testing of my application, I observed some memory leaks which were not related to the Application code but represents a set of Instruction sets. Also Instruments showed Foundation as the responsible library for the Leak (Extensive use of NSString,NSDictionary,NSArray which belongs to the Foundation framework). My application crashes after 10 - 15 mins of usage.The Crash report mentions, application crashed due to low memory.
Memory profiling using CLANG shows zero leaks. How do i solve these memory leaks?
Are these leaks the real culprit behind the crash? Are there any other tools available to check memory leaks?
I often find my leaks say they're caused by Core Foundation (or any other framework for that matter) but are really my own. With the exception of the Simulator, rarely will you find excessive leaking in the frameworks.
If you open up the detail panel to the right in Instruments you may find listed your App's methods in there. That will give you indication of where it could be coming from in your code. One leak can spring many other leaks, and you may have to find the top level culprit to get rid of the lower level ones.
You should not expect Clang to do anything but find the most obvious leaks. It's very handy, but that's it, just a helpful addition to compiling.
clang is not a leak checker. It only detects a small subset of issues.
For memory leak debugging you should focus on Instruments, specifically the Object Allocation and Leaks instruments. Be sure to understand the difference between leaks and other source of high memory usage though.
Once you've determined that objects are leaking, use Instruments to examine their allocation stack trace (so you can tell what object it is), and their retain/release history.
If it's not a leak, then I suggest investigating the instructions here:http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/
Most likely you have code that is creating the foundation objects. Leaks shows you the place of allocation but that is generally due to a call your code made to create the object. You can look at the call chain in Instruments and go back along the call chain until you get to your code - that is the place where you are causing the allocation. Now, for that allocation, look at your memory handling for that object: Do you release it some time later?
There are lots of ways you can fail to release memory property so it would be hard to guess which one you might be hitting. Ones I see when helping people include allocating an object and assigning it to an instance variable via a property with the retain attribute, something like this:
#property (retain) NSString* myString;
...
self.myString = [[NSString alloc] initWithString: #"foo"];
the alloc+init creates a retained object, the self.myString = increments the retain count again. If coded correctly, the dealloc method releases the property via one of:
[myString release];
or
self.myString = nil;
And that takes care of the retain added with the self.myString = but does NOT take care of the retain from creation. Solutions, ONE of the following:
myString = [[NSString alloc] initWithString: #"foo"]; // doesn't call the setter method so no assignment retain - but doesn't call the setter which might be bad if non-trivial setter.
self.myString = [[[NSString alloc] initWithString: #"foo"] autorelease];
autorelease releases the alloc+init retain.
Now of course this is a contrived example because you'd probably really use:
self.myString = [NSString stringWithString: #"foo"];
which is a class method returning an autoreleased string and avoids the problem. But the idea is to show a simple example to explain this type of issue.
There are many other ways to not release memory properly, but the advice to work your way back up the call-chain until you get to your code is the way to go look at where you are triggering the allocation of the memory and then you can figure out why you aren't releasing that properly.
Try to do some issues in u code:
1. Please avoid hide declaration like
NSString *string = [dictionary valueForKey:[dictionary2 valueForKey:#"something"]]
Correct code is:
NSString *key = [dictionary2 valueForKey:#"something"];
NSString *string = [dictionary valueForKey:key];
key = nil;
Try to avoid declaration with autorelease and local declaration like:
NSArray *array = [NSArray array];
If u do this, make sure that u have:
NSArray *array = [NSArray array];
.... some code where array is using;
array = nil;
Better idea is alloc and release immediately when u don't need object and put it to nil.
3. Check if u using correct setters. Probably better idea is avoid to using it, at my experience, deallocate class start leaks for getters and setters, which was using before.
If u post some part of u code, where u seen most leaks (instruments give u possibility to click on leaked objects and see volume of leaks in programming code) community can suggest more.

stringWithContentsOfURL leaking memory

Would it shed more light if I told that fetchHTML was being called in a seperate thread? I am also seeing several messages in the debug console such as:
_NSAutoreleaseNoPool(): Object 0xd92860 of class NSCFDictionary autoreleased with no pool in place - just leaking
_NSAutoreleaseNoPool(): Object 0xd92800 of class NSCFString autoreleased with no pool in place - just leaking
I am new to iPhone app development, Objective-C but not new to programming or C/C++. I am using the leaks performance tool and it shows many leaks. This is a 10.5 kb leak and it occurs on the line:
NSString * xml = [NSString stringWithContentsOfURL:urlobj];
The stack trace on this below is:
stringWithContentsOfURL
initWithContentsOfURL
initWithDataOfEncoding
...
Does anyone have an idea why this must be happening. I am under the impression that I get an autorelease object here and I can return this to the caller without calling retain. I am not using the xml object to store in an instance variable, just for processing.
Here is the function code:
- (NSString *) fetchHTML: (NSString* ) url{
#try
{
NSURL* urlobj = [NSURL URLWithString:url];
NSString * xml = [NSString stringWithContentsOfURL:urlobj];
return xml;
}
#catch( NSException *ex){
NSLog(#"Error fetchingHTML");
return nil;
}
return nil;
}
Yup; that shouldn't be leaking.
It might be a false positive in that the URL subsystem is caching the contents of the URL and doing so in a way where the pointer is no longer visible to leaks analysis.
If you can, retry the test on Snow Leopard. Leaks detection on Snow Leopard is significantly faster and more accurate.
I completely agree with you that this should not cause a leak. I've been coding in Cocoa/Objective-C for 2 years now, and that looks like it should work.
That being said, I notice that Apple's documentation indicates that the stringWithContentsOfURL: method is being deprecated. Perhaps it would work as follows:
NSString * xml = [[NSString alloc]
initWithContentsOfURL:urlobj
encoding:NSASCIIStringEncoding
error:nil];
return [xml autorelease];
As the error message says, there's no autorelease pool for the string to go into, and that creates a leak. NSAutoreleasePools exist on a per-thread basis. Cocoa creates one in the main event loop of the main thread, but that's the only one it creates for you. If you're somewhere other than the main thread and you're going to be dealing with autoreleased objects, you need to create an autorelease pool for that thread as well.
You can check out the NSAutoreleasePool docs for more information on how autorelease pool stacks work.