MemCheck helps to find memory leaks in your iOS applications. It can register alloc, retain and release calls for NS-objects and show detail information in console.
That's new edition of documentation. A old edition also works but shouldn't be used.
Add files from memCheckLib folder to your project.
add in the tail of your pch file
#define MEMTEST_ON
add in the top of the application: didFinishLaunchingWithOptions: function
#ifdef MEMTEST_ON
[NSObject turnMemCheckOn];
#endif
All actions should be run through parser:
po [parser run:@"your action"].
Action consists of arguments, filters and commands. All of them follow each other.
###Arguments### An argument describes which list of objects you want to use.
all - live objects which wasn't deallocated
dead - deallocated objects
heap %Number - live objects for a specified heap
leaks - suggested leaked objects
You can combine several arguments using '+' symbol. For example: heap 1 + heap 2.
###Filters### A filter removes unnecessary objects from list of objects
heap %Number - leave objects for a specified heap
withLiveOwners - leave objects with live owners. An owner of object is who contains a retain property on it.
withoutLiveOwners - remove objects with live owners
withoutOwners - leave objects without owners
withOwners - leave objects with owners
withOwnersLessThan %Count - leave objects with less than a specified number of owners
without %ClassName - remove objects with a specified Class
fromList - leave objects with class from a ClassesSet.m. The file should be generated for your project by a CreateClassesSet.rb script. You should call the script in a root folder of your project:
ruby ./CreateClassesSet.rb ./
Then you should replace base reateClassesSet.rb with a new one.
You can combine several filters after a gap. The result of first filter will pass to the input of second filter. For example:
heap 1 + heap 2 without UIImage withOwnersLessThan 5.
###Commands### A command performs specific actions with a filtered list of objects
markHeap - mark heap
markHeapWithName %Name - mark heap with specified name
print - print information about objects
saveGraph %PathToFile - save a input file for a dot program (http://www.graphviz.org/) to a specified path
showHeaps - show a list of saved heaps
You can combine several commands after a gap. All commands will not change the list of objects. For example:
heap 1 + heap 2 without UIImage withOwnersLessThan 5 print saveGraph /Users/yourname/Documents/dot/mem.txt.
###Using### To call an action you should pause your application in the Xcode debugger and type po [parser run:@"your action"] and press the "Enter". But a result will not be displayed immediately. The action will be started when you press the continue button. To stop automatically when the action will be finished you should add a breakpoint at the end of the parse: function in NSMemCheckParser.m.
###A description of objects### The library wraps an allocated object in NSMemCheckObject. There is a description for one of them:
2011-12-11 11:56:04 +0000 memCheckObject 0x68d0fd0 object 0x68cef80 stack 0x0 DEAD UILabel
owner (detailDescriptionLabel 2011-12-11 11:56:04 +0000 memCheckObject 0x68c3eb0 object 0x68c3de0 stack 0x68c4050 DEAD DetailViewController
owner (sceneViewController 2011-12-11 11:56:04 +0000 memCheckObject 0x68be640 object 0x68bf1d0 stack 0x68bf2f0 DEAD UIStoryboardScene )
)
2011-12-11 11:56:04 +0000 - the allocated time
memCheckObject 0x68d0fd0 - itself pointer
object 0x68cef80 - the pointer to the wrapped object
stack 0x0 - the pointer to a alloc stack of the wrapped object, it can be null
DEAD - that flag says that the wrapped objects is already deallocated
UILabel - the class of the wrapped object
If the wrapped object has an owner that information is displayed below after a "owner" keyword. Information of parent contains additional information at the beginning: detailDescriptionLabel - the name of property in the owner class which reference to the wrapped object
If the owner contains its owner then information about that is displayed below.
If the wrapped object contains 2 or more owners that is displayed shortly:
2011-12-11 19:33:54 +0000 memCheckObject 0x6abe390 object 0x68cfb10 stack 0x0 (0,0) UICFFont owner 4
To display all owners you should enter an "owners" command for a pointer of wrapped object:
po [0x6abe390 owners]
###Examples###
Print all allocated objects:
po [parser run:@"all print"]
Print the suggested leaked objects which have less than 5 owners:
po [parser run:@"leaks withOwnersLessThan 5 print"]
A most useful command to save information about your leaks:
po [parser run:@"leaks fromList withOwners withOwnersLessThan 5 without UIImage saveGraph /Users/yourname/Documents/dot/mem.txt"]
###Using saveGraph command### A saveGraph command creates a text file. In the above example its name is "mem.txt". To convert the file to a dot file we should run the next script:
dot -Tdot mem.txt -o mem.dot && open ./mem.dot
It will show a graph with objects, relations between them and marks of heaps.
Timeline and mark of heap is displayed at left part in the picture.
An arrow from the DetailViewController to the UILabel means that an object of DetailViewController contains an object of UILabel. A dotted arrow shows when an object dead. Live objects have a white background, dead objects have a gray background.
The first pointer of object reference to an object of NSMemCheckObject. The second pointer reference on object directly.
There is generated image for memCheck.xcodeproj:
###How the library finds leaks###
The library have two arrays. A memData array contains all allocated objects. A suggestedLeaks contains objects which I think is leaked.
Before a release call in a object I perform the next operations. I scan all retain properties in the object. If the object has one retain count I will put all his properties' object in the suggestedLeaks array. I do that because I make suggestion that programmer forgot add release call in the dealloc method of the object. If I am wrong an added object will be removed from the suggestedLeaks array when it dealloc will be called. In short that means that all objects which owners was deallocated are suggested leaked. Yes that's rough method but in practice it's a perfect filter of unnecessary object. But the library will display some live objects on the top of a graph.
###Using with ARC### Hmm, may be that is useful but I don't know. To allow that set -fno-objc-arc for all library files. For full description please see http://stackoverflow.com/questions/6646052/how-can-i-disable-arc-for-a-single-file-in-a-project.
###Known issues### After run action sometimes you may see the message
The program being debugged hit an ObjC exception while in a function called from gdb.
If you don't want exception throws to interrupt functions called by gdb
set objc-exceptions-interrupt-hand-call-fns to off.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function (objc_msgSend) will be abandoned.
press continue to continue action. If action was blocked repeat it.
Library can't register toll-free bridge objects (NSArray, NSDictionary, NSNumber and other).
Library registers objects relation through property only.