I am using Instruments to find memory leaks in my app.
When a object alloc, a blue block(line) display in Instrument, like this:
Screenshot of Instruments's timeline, showing the Allocations graph http://naituw.com/temp/instruments.png
When the object have been release, the blue line will disappear.
But when I make some operation in my application, some blue block left there, doesn't disappear, How can I know what those block actually is in the memory? Thanks!
Select the instrument and look in the list in the lower half of the window. It will show a table or outline (depending on the instrument) listing what the instrument recorded.
For the Allocations instrument, it lists things your application has allocated. Depending on the view settings, they may be objects that are still alive or all objects, even those that you have freed.
For the Leaks instrument, it lists things your application has allocated and leaked (i.e., no longer has any reference to). Note that you might still be wasting ever-increasing amounts of memory on things you will never use, not because you don't have a reference to it but because it's in a write-only cache (you stash it but never look it up) or similar situation. Bill Bumgarner calls this “abandoned memory”.
With either instrument, you can click on ➲ buttons within the list to drill deeper down into it, to see the list of allocations of a given type (e.g., all NSImages) or everything that happened to a single object, from birth to death. The latter is extremely useful for hunting down both leaks and over-release crashes, and is the reason why Instruments's Zombies template is so much better than NSZombieEnabled.
In leaks instrument these shows the memory allocations that took place at the particular time.
Related
I have a hard time figuring out, where my app is leaking. I have tested it with the "Instruments" profiling application by allocations, with heapshots. This is what I got:
As you can see, the allocations is increasing. It increases every time I transitions between two views, with an fade effect. In which of the following heapshots should I look in, in order to find the leak and what kind of objects should I look after, when I go through the heapshot/heapshots?
Thank you for the help in advance :).
ARC can only deallocate the memory if you are not holding any references to it anymore. Since the leaks instrument doesn't indicate any "real" leaks (in the sense of memory that you don't have access to anymore), you are probably seeing a case of abandoned memory. You are still holding references to objects which you don't need anymore, so they don't get deallocated.
It doesn't really matter which snapshot you inspect after the baseline. The list of objects in a snapshot can be somewhat overwhelming though... but often it helps to filter it down to your own classes. You can do this by typing your class prefix into the search field in the upper right. If none of your classes show up in the snapshot, you can at least look for classes which you directly use.
Also make sure to enable the "Record reference counts" option in the inspector pane of the allocations instrument. When you have this enabled you can click on the little right-arrow next to the objects listed in a snapshot (not the class name, but the object represented by its memory address) and see a complete history of this object. This makes it easier to see who is holding references to it.
Hope this helps!
Build your code with the 'Analyze' option; track down and eliminate every issue.
Please help me understand how can i use this statics shown in image.
How can i use heapshot effectively to detect memory leaks?
I have added image of Instrument using leaks.but i am unable to find exact location of memory leak.
Please guide me for this.
Basically a heapshot in this screenshot will display any objects that were created after the previous snapshot and that are still 'live' (have a retain count > 0).
The typical usage would be to hit "Mark Heap", then navigate into a view controller, tap a few buttons, perform a few actions, and then hit the 'back' button. Take another snapshot and examine the list of objects. You should make sure that there aren't any objects hanging around that should have been cleaned up. This may be things like the view controller itself, model objects, etc.
If you want to detect real leaks (unreferenced objects) use the Leaks tool. If you want to find other types of unbounded memory growth, i.e. objects that are still referenced and alive which shouldn't be, examine heapshots using the allocations tool like in this screenshot.
EDIT:
You added a Leaks screenshot to your original post. To see the stacktrace for where this object was allocated, click this button:
This should show you where the object was created. Then you need to figure out where the appropriate release call needs to go.
I recently watched one of the WWDC 2010 videos: Session 311 - Advanced Memory Analysis with Instruments. The link is here.
There is an interesting example in the video on finding Abandoned Memory. They say that it is often more important to debug than leaks but can be more difficult.
Abandoned Memory is defined as "Accessible allocated memory that is never used again".
A leak is defined as "Allocated memory that can no longer be reached."
The primary way to find Abandoned Memory is to take heap shots using the Allocations instrument.
However, after determining that I have abandoned memory in my code, I have found that it is really difficult to find out exactly where it is coming from.
I am looking for some good tips or resources for finding Abandoned Memory.
Thanks!
In Instruments, you can get a call stack for any object identified by a heapshot. Screenshot:
So what we've got here is a contrived case where I allocate a 1MB NSMutableData everytime the user taps a button. In the center-bottom pane, I've got 4 heapshots, and I have one expanded to show the objects that were created but not released since the last heapshot. I've highlighted a 1.25MB "non-object" allocation, and in the right pane, it shows me the exact call stack where this allocation occurred. One trick about that panel on the right is the slider along the bottom -- it controls the elimination of stack frames. If you want to see all the stack frames, drag it all the way to the right. Grayed out frames are those for which you don't have source code, and non-grayed-out frames are your code (or code you have both symbols and source for.) (Also, if you're not seeing the panel on the right, check the "View" buttons in the toolbar.) What other information are you looking for?
To summarize bbum's excellent blog post:
Profile your app using Instruments
Use the Allocations template
When the app isn't running, click the little i next to the Allocations track header and check Record reference counts; this will let you know where the items are being retained, not just where they are allocated.
Run your app, do something, then return to a default state. For example, open a new document window, then close it.
Click the "Mark Heap" button in Instruments.
Repeat steps 4 and 5 several times.
When you review the allocations in Instruments, you can click the right-arrow button to see a history of events for that instance, including all places it was allocated, retained, released, and autoreleased.
In my cocos2d application I have run through it using instruments and removed all memory leaks. I have my game outputting how much memory is in use on the screen and it is constantly rising as the game progresses until I eventually run out of memory. The amount of objects on screen doesn't increase by very much each level. Its a fairly simple game so i should not be running out of memory so soon.
I am removing all objects from a level when it ends and reallocating new ones when a new level begins. Instruments tells me there are no memory leaks. When i run through instruments to show me where the allocations are the bulk of the problem doesn't seem to come from one place its all of my objects.
Any ideas what the issue might be?
Just because instruments doesn't show leaks, doesn't mean you're not still allocating memory you're not using. Pay attention to the ObjectAlloc graph and see if that is constantly rising without falling off.
If you allocate memory that you aren't using and can't clean up, that's just as bad as a leak, even though you haven't technically leaked anything because you've stashed some unused reference somewhere.
Look at how much memory you actually need to use or to keep for future use at any point in your app, then treat anything else previously allocated as a leak and fix it.
In Objective-C when using autorelease objects be wary of circular dependencies!
If you create object A and then an instance of object B and pass A to it, so that B retains A, and A also retains B (for example by adding it as child to A) you can easily setup a circular dependency and thus both objects won't be released.
Tip: add a -(void) dealloc method to all your scene classes, and set a breakpoint there. If you change a scene and its dealloc method isn't called after the scene transition has finished, you're leaking this scene (it's not released).
Try to find that leak by looking for a setup that's similar to the one I described above.
Be careful about autoreleased objects, since they are not released immediately. If you have sections with lots of allocations and autoreleasing, try using specific autorelease pools on them.
It happened to me when creating huge decision trees (using NSArrays) for a game AI.
A great way to check for objects that are aggregating in memory is to use Instruments' new (in Xcode 3.2.3) Heap Shot functionality.
Use the normal Allocations instrument against your running application. Perform a series of repetitive events that should come back to some known state (for example, go one level down in a navigation controller and come back). Every time you do this, click on the Mark Heap button in the left sidebar for the Allocations instrument (under the section heading Heapshot Analysis).
What this will do is mark the heap at each of the starting points for this repetitive action and compare the objects that have been created by that point with the objects that had been created by the time you marked the heap last. Only objects that have been created between those two points and are still alive in memory will be listed.
If you are accumulating objects, but they are either not leaks or are being missed by the Leaks tool, they should show up here. I've found a number of subtle memory buildups this way, particularly when you pair this with the UI Automation instrument to automate the repetitive actions you're testing.
The bulk of the problem seem to be that Sprites don't get released in cocos2d unless all actions have been stopped on those sprites. This is done using stopAllActions. Cheers for all the suggestions.
I have been hunting down memory leaks for some time in my app. As of right now, as I flip back and forth between two views while watching the memory monitor instrument, the real memory fluctuates between 5 and 6 megs. This is all fine -- as far as I can tell everything is getting released properly when I pop back off a view. However, the virtual memory continues to increase and my available real memory drops rapidly every time I push the view back onto the view stack (even though the real memory usage of the app isn't increasing). Eventually, this all leads to an out of memory crash. Is this a telltale sign of any specific issue, or am I just missing a memory leak somewhere?
EDIT: The odd part is, I get an out of memory crash while the app is still only using up about 5 megs of real memory.
Do not use -retainCount.
The absolute retain count of an object is meaningless. It is an implementation detail. It may be influenced by many factors well beyond your code.
You should call release exactly same number of times that you caused the object to be retained. No less (unless you like leaks) and, certainly, no more (unless you like crashes).
See the Memory Management Guidelines for full details.
In this specific case, you are leaking memory but in a way that leaks can't find it. The objects that are leaked are still connected to your overall application's object graph somehow. Maybe through a notification, maybe through delegation, doesn't matter -- leaks sees the reference and concludes that the object might still be live.
Use the Allocations Instrument. Configure it to only track live allocations (since you don't care about objects that have been deallocated). Do some stuff with your app. Check out what Allocations knows about and explain why all those objects should stick around. You can use the data mining facilities to filter down to just your objects.
Anyway, you can also use the "Build -> Build and analyze" option to find suspicious non-conventional code.
Another reason why you may have memory lost in lower API layers is if you don't remove all your views from your view hierarchy (aka : not calling [view removeFromSuperview] everywhere). At least that's what seemed to have happened to me.
Note that most of time this isn't required, as you would simply release the main view and all its subviews, then rebuild it from the view controller when needed. Things start to get more tricky when you're not releasing the whole hierarchy but instead simply remove some of them from the hierarchy.
In that case, I came to the conclusion that you may have buffers or layers still cached in lower API parts, and in that case your Allocation instrument won't help you.
In order to monitor correctly you'll need to use the "Memory Monitor" (in System). You'll see that the "Physical Memory Free" line dropping close to 0 is the most reliable indicator that a Memory Warning will be issued.
Another advantage of using this instrument, is that you can attach it to a running process, thus making it possible to have console output and instrument running together easily.
Circular references also won't be counted in Leaks but you can track those in Allocations. Best bet is to fire up Allocations and get to a state where you think everything should be gone (or certain objects should be). If they're hanging around go dive in to them and look at where they've been retained and sort out the proper memory ownership/releasing.
As for Allocations, there are some things that it doesn't track that can affect the overall memory. Some of the things include some CGImage backing stores, some CoreAnimation stuff and some database stuff.
Have you used the "Leaks" Performance Tool? And check out the logs in Organizer to see if there's anything there.
Also look into the dealloc for the view controllers and make sure you are properly releasing all of it's objects?