In the initialization of my app, I am reading some data out of a Core Data managed object context. For some reason, even though the executeFetchRequest line of code is called only once, I am seeing 5 living entries in the Instruments Allocations tool object listing. For example, if I drill down into the source code from within Instruments, I see this:
I set a breakpoint on this line, and verified that the app is stopping on this line only once. However, this is what I see as a result in Instruments:
If I look at the stack trace for each of these 5 objects, it is exactly the same, all pointing back to line 135 as shown in the first screen shot. (As you can see, I have tried a few different scenarios and all of them have the same result.)
So I have two questions here.
Question #1: Why do I see 5 living objects?
Question #2: Why are the objects living any way? From what I can tell, everything is being released correctly, and wrapped inside autorelease pools that should take care of these objects.
I am on Xcode 4.2 with the iOS SDK 5.0. Any ideas would be appreciated. Thanks.
The CFData instances are just chunks of data. Perhaps they represent records in the database, but not knowing the internals of CoreData, that's just speculation. They could represent cached data held by the managedObjectContext, but that too is mere speculation.
If you're not seeing any leaks reported, I would not worry too much about it.
Although if anyone has more insight into this, please chime in.
Related
I have found few memory leaks when I am running my application. For your reference, I am sharing the screenshots of Instrument debug logs and also Xcode Debugg memory graph tool. I am not getting what is going wrong here. Please help me to resolve memory leaks.
Please help me to fix the memory shows in the image. Thank you.
I know this is an old question, but a few observations.
When you have a lot of objects that are leaking, focus on high level objects (especially your own classes). We do not care why the array was not released. We care about why the item that is keeping a strong reference to it was not released. XTubeManager and GlueTubeManager are probably good places to start searching, but I don't know what other high level objects appear in the panel on the left.
When you have leaks, it is very useful to use the “Malloc Stack Logging” feature. So edit your scheme (command+<; or “Product” » “Scheme” » “Edit”) and go to the “Diagnostics” section and temporarily turn on “Malloc Stack Logging”:
Then, when you select a leaked object, you can see where it was instantiated but using the memory inspector panel on the right:
Look for entries in that stack trace that are white (your code), as opposed to all the system items that are in gray. When you hover items in that stack trace, there is even a little arrow that lets you jump to the code in question. In my example, the leaked object was instantiated in viewDidLoad.
This will not tell you why it leaked, but you will be able to see where the object in question was instantiated in your code, and you can start your investigation from there, diagnosing why an object created at that point in your code still has lingering strong references.
Remember to turn off the “Malloc Stack Logging” feature when you are done with your diagnostics.
As an aside, when we see URLSession objects that were not released, that begs the question of whether you instantiated a URLSession object (rather than using the shared instance) and neglected to call finishTasksAndInvalidate. Ideally, you would have a single URLSession and reuse it for all network activity (or use the shared instance), but if you must instantiate sessions, make sure to invalidate them when you are done.
You do NOT need to use Instruments. That's the old way. Use Xcode itself.
See Visual Debugging with Xcode
- 24:45
Watching the video is a MUST, but the summary of the video is as such:
There are two type of memory problems. You just have to repeat a flow in your app 2-3 times to be certain the memory graph has caught it
Leaks. Xcode will annotate this with purple icon. Possible are: delegates, closures
Abandoned memory. Xcode will not annotate this. But it's still increases your memory footprint. possible examples are: A repeating timer that is never invalidated, NotificationCenter, A never ending DispatchWorkItem
For Leaks the memory graph is a loop ie two way.
For Abandoned memory the graph is NOT two way. It's just an object one that Apple categorizes as 'root path' referencing your object and never letting it go. For more on this see here
In this case, just because some tool says you’ve got a memory leak doesn’t mean you have one. The amount of data seems to be less than 1MB, that’s nothing. Your tool suspects there’s a leak because data was allocated and not released, but these are single objects. Quite possible that memory is going to be released or reused later.
Use your software for hours and check if memory usage gets larger.
Memory on mobile devices is a shared resource. Apps that manage it improperly run out of memory, crash, and suffer from drastically decreased performance.
so to fix it follow this steps
Open Xcode and build for profiling.
Launch Instruments.
Use the app, trying to reproduce as many scenarios and behaviors as possible.
Watch for leaks/memory spikes.
Hunt down the source of the memory leaks.
Fix the problem.
I am developing an app for the iPhone and am encountering some memory management issues. During execution of the app the live bytes continuously increase without bound. I have tried to track down the issue within my code but cannot seem to find anything that would cause the live bytes to increase so dramatically. The one thing that I have noticed during execution is that the allocation for CFString(Immutable) increase the most rapidly and never decrease or stay constant. Does anyone have any idea why this may be happening? All that the app is doing during this execution is populating a table view from a local array or strings, then downloading another array of string objects and populating a different table view. I am using ARC.
Given the lack of anything concrete to go on, I'll give you somewhat general counsel:
See Finding leaks with Instruments for guidance on how to use Instruments to find leaks.
For specific advice how to go from you allocations, to a more meaningful analysis of the source of those allocations, see point #4 of this Stack Overflow answer. In short, highlight one of your unexplained jumps in allocations, set the bottom window to show you the call tree, hide system libraries, and see in which of your routines the memory is being consumed.
Also, don't overlook the static analyzer, which is especially important if you don't use ARC, or if you use any Core Foundation calls.
Are you doing anything with Core Foundation functions? If so, you obviously need to know that you either have to explicitly transfer ownership to ARC (with either CFBridgingRelease or __bridge_transfer) or manually call CFRelease. The static analyzer of my prior point would point this out to you, though.
I have developed application and all is well. As well, I also keep memory foot print very low.No leaks show during application run. I tested application more than two hour and there is no crashing report. But when i checked application on instruments at that time it's show me following leaks.I have checked my app but there is no such leaking object. "Even I used app continue 12 hour and it didn't crash or stop".
//Here the screen shot of instruments.
///>>>>>>Here, I uploaded latest screenshot of leaks.It may help somebody to understand where the leak is.
// I think it's library file leaks(CoreFoundation)...Please Suggest What to do..
Please help me, This is really screw me up.
Thanks.
Not all of the 'memory leaks', are actual leaks. And some of the reported issues may be caused by Apple libraries themselves. Typically all the singletons, static variables, and some c level variables are 'leaked', but only once and are not considered a threat to memory.
Foundation classes such as NSString, NSArray, etc. are optimized to handle heavy workload. And some objects may be kept in the memory to be reused later. Such as #"".
So unless the issue is accumulating over time, just go for it, submit your app as it is. You still can fix it later, if necessary.
Hey analyze you code using "command+shift+b" and fix all leaks whatever coming after analyzing, submit it to app store. I don't think we can fix all leaks shown by instrument, so better to go with command+shift+b. I think we should use instrument only when getting memory warning and crashes due to insufficient memory.
I build a parsing algorithm using NSXMLParser.
Im having doubt as to what is the best strategy for keeping my memory usage on a minimum.
I have a valueObject (e.g. "Person") this object has ≈ 30 NSString properties, while parsing the xml I continually alloc and release a temporary Person object as the nodes are traversed.
I checked this and there is only one of these Person objects instantiated at any time.
When a node is traversed and a Person is "build" I pass the Person to a NSMutableArray and release this Person. Seems no problem there. (I'll need the array for a tableView).
When I reach around 50+ Person objects in the array my app just quits, didReceiveMemoryWarning doesn't get called, no other warnings, no parseErrorOccurred, nothing?
If I limit the number of Persons in xml the app does just fine, I haven't been able to find any memory leaks with Instruments.
I think that I simply can't hold 50+ Person objects in an array… seems a bit harsh, but I haven't got much memory experience with the iPhone, so this is just a guess.
The xml is search results from which the user probably only needs a few, so persisting them to my core model to keep them around for display seems a bit crazy.
What would be a good strategy for keeping these Person objects around? or am I missing a huge memory leak since the iPhone should be able to handle much more than this?
Hope some experienced developers can point me in the right direction:)
Thank you!
Despite NSXMLParser being a SAX-based parser it does not support parsing an input stream, which means that the entire XML string you are parsing is kept in memory. This on its own is a big issue, but as you parse the problem gets worse as you start duplicating the string data from the XML in your Person objects.
If your strings are really big, you've got the second problem of having too many parsed Person objects in memory at one time.
The first problem can be solved by using AQXMLParser from Jim Dovey's AQToolkit library, which provides an NSXMLParser-like API but with support for streaming the data from disk.
The second problem can be solved using a disk-based persistence technology, like Core Data, SQLite Persistent Objects, or even just storing the Person objects on disk yourself.
How long are those strings? Generally, on the iPhone 3G and older models, your app should have a minimum of about 20 MB of memory available (much more on the 3Gs). This is no absolute rule, of course, but a decent rule of thumb. To occupy this much memory with 50 objects would mean ~400-500 KB per Person object. Is this in the ballpark? If so, you will probably need a memory management strategy that does not keep all objects in memory at the same time. Core Data can probably help you a great deal in that case.
If you did not receive a memory warning it is probably not the reason your app is quitting. In Xcode go to the organizer, and select the device, then click on the console tab. If they app was shutdown for memory reasons there will be a system message in the console log saying it is killing the app due to memory pressure.
The answer is to chop up the incoming stream, I wrote a post about it some time ago:
https://lukassen.wordpress.com/2010/01/15/feeding-nsxmlparser-a-stream-of-xml/
I have an iPhone app that is running great in the simulator. It responds well to the memory warnings by getting rid of everything that is not absolutely essential. When I run it on the device, it runs well. But after a certain amount of usage it crashes with error code 101 - which, from what I can tell, is the OS killing it due to memory usage. I can see the memory warning (I'm logging it), and my app responds to it, but dies shortly thereafter.
If I look at the app in Instruments (either on the device or in sim), it doesn't find any leaks. In addition, the net memory usage is in the range of 600-700k bytes. Transitioning from the different views of my app increases memory usage (as expected), but when the views and controllers are released and dealloc'd, the memory usage never quite goes as low as it was. However, the addition is usually only something in the range of 1000-2000 bytes. So while Leaks shows me no leaks, I suspect there is an issue somewhere. I've also looked at all of the objects I'm allocating, and all of them seem to be reclaimed as expected. The only objects I see that keep increasing are GeneralBlock-N (where N is some number)
Should I not pay any attention to Instruments net usage figure? What would be the next steps in trying to diagnose the issue?
ADDED: I'm not making any calls to malloc() or any CoreFoundation libraries that would return a buffer that I'm responsible for. The only non-Obj-C calls I'm making are logging statements to NSLog.
One quick thing to try is running the Clang static analyzer. This will find some, but not all, issues in your code that you might be missing. It checks the code at compile time, so it's by no means infallible, but will almost certainly find most glaring problems.
You should also run your application with the memory monitor instruments to see overall system usage on the device.
Leaks only finds memory that is not referenced by anything, but still retained.
What you are seeing is that you have left memory retained, and still referenced by something.
One thing to look for especially, is that if you have passed a reference of a class to something else as a delegate that you free it in your dealloc method.
Similarly, if you have subscribed to any notifications you should unsubscribe in viewWillDisappear: (if you use the general unsubscription method in a view controller do not forget to re-subscribe to the memory warning notification.
Timers are the same way, deactivate them when a view goes away and re-enable them when the view comes back (unless of course you need a timer running the whole time your application is running).
Basically be suspicious of anything you give a reference of a class to, and try to figure out how you might eliminate that link whenever possible (either in dealloc or viewWillDisappear: or both).
Here's a summary of what I've learned (thanks to some excellent answers and comments):
Object Allocation is NOT the same as Memory usage. The answer to my question about ObjectAlloc's net bytes element is that you shouldn't be paying attention to it - at least not when determining issues with the amount of memory you are using or whats causing it to crash. It doesn't reflect the true memory usage of your application.
My amatuerish guess is that ObjectAlloc only shows you the memory taken up by the direct object itself. So if you have an UIImageView, it takes up just a handful of bytes to store the various properties, but it might be pointing to an image in memory taking up a bunch of space. Therefore, looking at ObjectAlloc is helpful only in making sure you're not creating and keeping objects around, it won't give you an idea of how much memory you're using or how much you can use before crashing.
MemoryMonitor will give you the total memory usage. You can constrain it to viewing only your app's usage by using the search tool in the bottom right of the Instruments window.
Both ObjectAlloc and Memory Monitor (as well as the Leaks tool) are plugins for Instruments - just in case thats not obvious to someone else. You can launch Instruments from within XCode by doing Run -> Start with Performance Tool. Once inside of Instruments, you can open the Library and add new plugins to monitor different aspects of performance.
One thing to look for is circular references.
(I don't want this to sound patronising - just want to make sure I'm being clear:) If object a refers to object b and object b refers to object a, there may not be a reported "leak" because all the memory is still referenced - but this may be an orphaned island of objects, seperated from your app and never reclaimable. Of course it may involve more objects ( a refers to b, b refers to c, c refers to a, etc).
If you're building up a graph of objects somewhere, and there are any back or cross references, be sure to break the circles if you release the root (there are different ways of doing this. The simplest is probably to make sure each class in question has a releaseAll method, or similar - which calls releaseAll on it's child objects, then releases the child objects - but this isn't always the best solution).