< Previous PageNext Page > Hide TOC

Finding Memory Leaks

Memory leaks are blocks of allocated memory that the program no longer references. Memory leaks are bugs and should always be fixed. Leaks waste space by filling up pages of memory with inaccessible data and waste time due to extra paging activity. Leaked memory eventually forces the system to allocate additional virtual memory pages for the application, the allocation of which could have been avoided by reclaiming the leaked memory.

The malloc library can only reclaim the memory you tell it to reclaim. If you call malloc or any routine that allocates memory, you must balance that call with a corresponding free. A typical memory leak occurs when a developer forgets to deallocate memory for a pointer embedded in a data structure. If you allocate memory for embedded pointers in your code, make sure you release the memory for that pointer prior to deallocating the data structure itself.

Another typical memory leak example occurs when a developer allocates memory, assigns it to a pointer, and then assigns a different value to the pointer without freeing the first block of memory. In this example, overwriting the address in the pointer erases the reference to the original block of memory, making it impossible to release.

Apple provides the MallocDebug application and leaks command-line tool for automatically tracking down memory leaks. You can also track down leaks manually using other analysis tools, but that task falls under the category of finding memory problems in general and is covered in “Examining Memory Allocation Patterns.” The following sections describe the MallocDebug and leaks tools and show you how to use them to track down memory leaks.

Contents:

Finding Leaks With MallocDebug
Using the leaks Tool
Finding Leaked Autoreleased Objects
Tips for Improving Leak Detection


Finding Leaks With MallocDebug

The MallocDebug application is a graphical tool for diagnosing all types of memory problems. MallocDebug includes a memory-leak analysis tool that you can use to identify leaks in your program. The interface for MallocDebug displays potential leaks using a call-graph structure so that you can easily locate the function that generated the leak.

Performing a Global Leak Analysis

MallocDebug uses a conservative garbage-collection algorithm for detecting leaks. This algorithm searches the program’s memory for pointers to each malloc-allocated block. Any block that is not referenced at all by the program is marked as a leak.

To initiate a leak search in MallocDebug, do the following:

  1. Launch MallocDebug.

  2. Open a new window and select the executable you want to examine.

  3. Click the Launch button.

  4. Exercise the application features to build its memory profile.

  5. In MallocDebug, select “Leaks” from the analysis popup menu to display the memory leaks in your application.

  6. Use the call-graph data in the browser to find where the memory was allocated.

Figure 1 shows the MallocDebug main window with the Leaks option selected for viewing. When you select any of the leak-related options from this popup menu, MallocDebug initiates its leak-detection analysis. It then displays the results of the analysis in the browser window. Each entry in the browser includes the amount of memory leaked from that function.


Figure 1  MallocDebug main window

MallocDebug main window

The leak analysis performed by MallocDebug identifies all memory that has been leaked since the application was launched. “Finding Leaks for Specific Features” describes a way you can use MallocDebug to isolate memory leaks in your application.

Finding Leaks for Specific Features

The leak analysis tools in MallocDebug perform a global search for leaks in your program. However, there are other types of leaks that MallocDebug cannot identify. These are leaks caused by your code allocating a block and then not freeing it. You must identify these leaks yourself using the MallocDebug sampling features. To find these leaks, do the following:

  1. In the MallocDebug window, select "Allocations from mark" from the analysis popup button.

  2. Click the Mark button.

  3. Exercise the target feature of your application.

  4. In MallocDebug, click the Update button to display the memory allocated since the Mark button was clicked.

  5. Look for any newly-allocated buffers. These may be buffers your code forgot to free after it was done with them.

Using the leaks Tool

The leaks command-line tool searches the virtual memory space of a process for buffers allocated by malloc but no longer referenced. For each leaked buffer it finds, leaks displays the following information:

If leaks can determine that the object is an instance of an Objective-C or Core Foundation object, it also displays the name of the object. If you do not want to view the contents of each leaked buffer, you can specify the -nocontext option when calling leaks. If the MallocStackLogging environment variable is set and you are running your application in gdb, leaks displays a stack trace describing where the buffer was allocated. For more information on malloc debugging options, see “Enabling the Malloc Debugging Features.”

The leaks tool has some advantages over MallocDebug when it comes to detecting leaks in complex data structures. For example, the leaks tool correctly handles leaks in circularly linked structures. It can also identify leaks in groups of connected nodes. MallocDebug may not correctly identify leaks in these types of structures.

Note: The leaks command-line tool is located in /usr/bin.

Finding Leaked Autoreleased Objects

If a Cocoa object is autoreleased without an autorelease pool in place, Xcode sends an a message to the console warning you that the object is just leaking. Even if you are not writing a Cocoa application, it is possible to see this same type of console warning. The implementation of many Cocoa classes is based on Core Foundation types. If your application uses Core Foundation, it is possible that the leaks are occurring as a result of calls to that framework.

To find memory leaks of this type, use the debugger to put a breakpoint on the _NSAutoreleaseNoPool function. This function is declared in NSDebug.h in the Foundation framework. When the debugger reaches that function, you should be able to look at the stack crawl and see what piece of code caused the leak.

Tips for Improving Leak Detection

The following guidelines can help you find memory leaks quickly in your program. Most of these guidelines are intended to be used with the leaks tool but some are also applicable for use with MallocDebug.

Most unit testing code executes the desired code paths and exits. Although this is perfectly normal for unit testing, it creates a problem for the leaks tool, which needs time to analyze the process memory space. To fix this problem, you should make sure your unit-testing code does not exit immediately upon completing its tests. You can do this by putting the process to sleep indefinitely instead of exiting normally.



< Previous PageNext Page > Hide TOC


© 2003, 2006 Apple Computer, Inc. All Rights Reserved. (Last updated: 2006-06-28)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.