I'm trying to track down some peculiar memory behavior in my Cocoa desktop app. My app does a lot of image processing using NSImage and uploads those images to a website over HTTP using NSURLConnection.
After uploading several hundred images (some very large), when I run Instrument I get no leaks. I've also run through MallocDebug and get no leaks. When I dig into object allocations using Instrument I get output like this:
GeneralBlock-9437184, Net Bytes 9437184, # Net 1
GeneralBlock-192512, Net Bytes 2695168, # Net 14
and etc., for smaller sizes. When I look at these in detail, they're marked as being owned by 'Foundation' and created via NSConcreteMutableData initWithCapacity. During HTTP upload I'm creating a post body using NSMutableData, so I'm guessing these are buffers Cocoa is caching for me when I create the NSMutableData objects.
Is there a way to force Cocoa to free these? I'm 90% positive I'm releasing correctly (and Instruments and MallocDebug seem to confirm this), but I think Cocoa is keeping these around for perf reasons since I'm allocating so many MSMutableData buffers.
If you're certain you're releasing the objects you own correctly, then there's really nothing you can (or should) do. Those blocks are, as Instruments says, owned by Foundation because NSConcreteMutableData, a Foundation object, created them. It's possible that these are some sort of cache that NSData is keeping around on purpose, but there's no way to know what they are.
If you believe this is a bug, you should report it at http://bugreport.apple.com. The rules of memory ownership apply to classes that don't manage memory well, too.
Also, this might be a silly question, but which option are you using for the Object Alloc tool? All objects created or Created and still living? You might be looking at allocations that don't matter anymore.
Related
I have written a windows service using .NET technologies. I am using `JetBrains dotMemory' tool to understand the memory leak.
I am getting below report but as a new bee I am not sure how to read this.
System namespace is showing more survived bytes. But how do I know which code is the root cause of memory leak?
At the first your should decide which kind of memory issue you are going to find
Constantly growing memory consumption - get base snaphsot, get another after memory consumption is increased, open snapshots comparison, open new objects created after first snapshot, look at them to understand which should be collected.
Ensure that some key object doesn't leak - set your app in a state when some object should not be presented in memory (e.g. close some view), get snapshot, using filter on "Group by type" view to ensure that this object is not presented in memory.
Memory traffic - get base snapshot if needed, run action/algorithm in your app which you want to check, get snapshot. Open "Memory Traffic" view, look if it looks as you implemented or more objects then you expected were allocated during the action.
Grab this free book for other possible memory issues.
P.S. Only you as an app author can answer the question, is it a problem or it is as designed.
You should look at the survived bytes / retained bytes which will point you to the base instance or the root object of the creation. It depends on your application design and implementation to decide whether the specified object in the memory should be retained or not.
If you identify the root object of the creation, you should try to separate the linkage and make the .net garbage collector to automatically collect the unwanted objects.
There is no fixed flag points to identify memory leaks.
Using ANTS Memory Profiler
Using Windbg or here
One source of memory leaks are the event handlers that are not being de-referenced.
Example:
myClass.DoSomething += Event_DoSomething
You need to make sure the resources are being clearead like below:
myClass.DoSomething -= Event_DoSomething
I have a WinRT application which uses many (sometimes large) images. The images are stored on disk, but it takes some time to load the images, which causes a visual hiccup. To fix that, I load the images beforehand and store them into a cache.
However, I'm a bit hesitant to store an arbitrary number for images in memory, and would like to use a cache that is automatically cleaned when memory gets low.
How would I go about implementing this? On iOS there is a didReceiveMemoryWarning method, but I can't find an equivalent method for WinRT.
If using .NET you could try holding weak references to images in the cache and so when you use them - they won't be garbage collected, but if you don't - they will be collected when memory pressure occurs. When retrieving images from the cache - you'd simply check if the weak reference is alive and if it is not - you'd reload the image before returning.
I'm afraid that asking this question may result in some downvotes, but after making some not satisfying research I decided to take a risk and ask more experienced people...
There are many questions here referring to some specific problems connected with the XCode Analayzer Tool. It seems to be very helpful solution. But I would like to ask you - as a beginner in iOS world - what kind of memory management stuff cannot be noticed by this tool.
In other words, are there any common memory management aspects, about which the iOS beginners should think "Oh, be careful with that, because in this case XCode Analyzer may not warn you about your mistake"...
For instance, I've found here Why cannot XCode static analyzer detect un-released retained properties? that:
(...)the analyzer can't reliably detect retain/release issues across
method/library boundaries(...)
It sounds like a good hint to consider, but maybe you know about some other common issues...
The analyzer is very good at finding the routine leaks that plague new programmers writing non-ARC code (failures to call release, returning objects of the wrong retain count, etc.).
In my experience, there are a couple of types of memory issues it does not find:
It cannot generally identify strong reference cycles (a.k.a. retain cycles). For example, you add a repeating NSTimer to a view controller, unaware that the timer maintains a strong reference to the view controller, and if you don't invalidate the timer (or do it in the wrong place, such as the dealloc method), neither the view controller nor the timer will get released.
It cannot find circular logic errors. For example, if you have some circular references where view controller A presents view controller B, which in turn presents a new copy of A (rather than dismissing/popping to get back to A).
It cannot find many non-reference counting memory issues. While it's getting better in dealing with Core Foundation functions, if you have code that is doing manual memory allocations (such as via malloc and free), the static analyzer may be of limited use. The same is true whenever you're using non-reference counting code (e.g. you use SQLite sqlite3_prepare_v2 and fail to call sqlite3_finalize).
I'm sure that's not a complete list of what it doesn't find, but those are the common issues I see asked about on Stack Overflow for which the static analyzer will be of limited help. But the analyzer is still a wonderful tool (it finds issues other than memory issues, too) and for those individuals not using ARC, it's invaluable.
Having said that, while the static analyzer is an under-appreciated first line of defense, you really should use Instruments to find leaks. See Locating Memory Issues in Your App in the Instruments User Guide. That's the best way to identify leaks.
I've just spent an entirely too long amount of time screaming my head off at NSURLCache, so I offer this bit of advice in the hope that others can avoid my misfortune.
It all started off reasonably enough. My new app project only targets iOS 5 and above, so I thought I could take advantage of the new NSURLCache implementation for all my web caching needs. I needed a custom subclass of NSURLCache to handle a few special tasks, but that all seemed to be helpfully supported by the API. A quick read of the documentation, and I'm off to the races:
[NSURLCache setSharedURLCache:[[MyCustomCache alloc] initWithMemoryCapacity:8 * 1024 * 1024 //8mb
diskCapacity:32 * 1024 * 1024 // 32mb
diskPath:#"webcache.db"]];
I figure an 8mb cache is fine to start, and I'll back it with a larger disk cache so we can serve more of our larger images locally. I hook up the rest of my network code to use NSURLConnection (actually, I used MKNetworkKit, but that turned out to be irrelevant), and expect great things from my cache. Sure enough, all the requests that are supposed to be cached are dutifully getting saved to the cache, and responses are dutifully flying back quickly when they are served from the cache. It's a regular production of Pirates of Penzance with so much duty flying around in my networking stack.
Except something's not adding up. Requests that can be served from the cache are still going out over the network. Except when they aren't. It appears totally random and intermittent whether the cache is actually used to serve a request. I tear out my hair in frustration and dig through literally everything trying to figure out what's going on. I build test apps, set breakpoints all over the place, tear through packet traces, read every word on the internet that mentions NSURLCache, experiment with cache-control headers, comment out code, bypass my subclass, and even resort to painstakingly tracing through the assembly for NSURLCache and its CFNetworking friends to try to understand what mysterious logic lies beneath. I massively improve my knowledge of ARM and Objective-C calling conventions and learn a fair bit about low-level debugging, but get nowhere in actually figuring out what's going on. The whole thing is feeling a lot more like Iolanthe's Nightmare Song than the benign dictatorship of the Pirate King and I'm pretty much on the verge of throwing it all away.
TL/DR version: NSURLCache appears to be working, but randomly doesn't return the cached results even though it has them available.
Eventually, I try a different permutation of all the bits I've been fiddling with. I set both the memory and disk cache sizes to 8mb.
Lo and behold, all the weirdness goes away! Everything that's supposed to be cached is getting saved. And everything that is supposed to come from the cache is getting served without network requests.
It seems that the NSURLCache implementation in iOS5 still isn't complete. It does use the disk and memory caches (unlike iOS4 and earlier, which only implemented the in-memory cache), but it doesn't actually pass through the memory cache to the disk cache when a request misses. As such, it's basically blind luck (well, blind luck influenced by all your other network and cache usage) whether a given response happens to be in memory or not at the right instant. This is probably useful to reduce flash memory file IO on the device, but insanely obnoxious if you expect rational behavior from the class.
And so with laughing song, and merry dance, I check in my two-line fix and make haste for the bar, eventually sharing this knowledge with SO (and an Apple bug report) in the hope that no one else has to go through this pain again.
The moral of this tale of woe: strange and evil things will happen if you try to use NSURLCache on iOS5 with a disk capacity larger than the memory capacity. Don't do this. And avoid making enemies of magical fairies.
FWIW here's my final solution:
https://gist.github.com/3245415
it requires using FMDB, but the results are pretty good.
I am developing an application in cocoa .I need to parse a iTunes XML file of large size(about 25Mb).I am using the following code snippet now
NSDictionary *itunesDatabase = [NSDictionary dictionaryWithContentsOfFile:itunesPath];
But this is a little bit slow
Is there any faster method to load the entire data to a dictionary??
The reason you're having such slow performance is because NSDictionary reads everything into memory all at once. For a large iTunes library, this can take a long time and -- feel free to confirm this with Activity Monitor -- a metric assload of memory. (This is the precise technical term for that amount of memory)
The alternative in these situations is to use a callback-based XML parser (generally known as "SAX" parsers). These parse XML documents an entity at a time and call your callback methods. In Cocoa, the NSXMLParser class provides this functionality. You set your class as its delegate, call the parse method, and the parser starts calls the delegate methods as it reads tags, attributes, text, etc. in the XML file.
Now, this is obviously harder than just loading everything into an NSDictionary and walking the resulting tree of objects. You'll need to keep track of state information yourself. And you'll have to "build up" your objects progressively, so organizing your classes can be difficult.
However, you can ignore the XML you aren't interested in, and that saves a lot of memory. And, depending on what data you're getting out of iTunes, you may also be able to end the parsing as soon as you've gotten the data you need. Even if this does end up taking quite a while, at least you'll be able to show your user a progress bar or some other indication that your program is working, which is much better than just hanging for 10-20 seconds while NSDictionary loads a giant XML file.
If you're able to use third-party frameworks, run, do not walk to EyeTunes. (BSD license.) It's an abstraction layer around Apple Events for communicating with iTunes, and as such it doesn't parse the XML database directly (I think, it's been a while since I've used it), but you'll have get/set access to anything in the XML.
Try to use libxml:
http://www.cimgf.com/2008/08/18/cocoa-tutorial-libxml-and-xmlreader/
To minimize highest memory footprint, create and drain NSAutoreleasePool in your loop