How to Use the leaks Command in macOS Terminal to Detect Memory Leaks in Running Applications

Tracking down memory leaks in software applications running on macOS can be challenging, especially when attempting to diagnose background processes, command-line utilities, or third-party background services without attaching a heavy IDE. Apple includes a native diagnostic utility called leaks within macOS. Operating directly from the Terminal, leaks examines the active address space of running Mach-O processes to detect dynamically allocated memory blocks that are unreachable by active pointers—identifying genuine leaks before they lead to memory pressure or app crashes.

How the leaks Command Analyzes Process Memory

When an application allocates memory using standard memory managers (such as malloc, calloc, or Objective-C/Swift objects) but discards all references without calling free() or releasing the reference count, that allocated block remains orphaned in RAM. The leaks tool reconstructs a directed graph of all references in the process address space:

  1. It scans memory segments including thread registers, stacks, global data segments, and reachable heap nodes.
  2. It identifies memory blocks that have no valid incoming references from any root node.
  3. It flags these unreferenced allocations as memory leaks and reports their size, memory address, and allocation backtrace.

Auditing Active Processes by PID

To audit an active process, open Terminal (found in /Applications/Utilities/). Because inspecting foreign process memory spaces requires Mach task port entitlements, root privileges (via sudo) are standard when inspecting system processes or third-party daemons.

Finding the Target Process ID

Locate the process identifier (PID) of the application you want to inspect:

pgrep -f "TextEdit"

Running the Leaks Audit

Execute leaks against the targeted PID:

sudo leaks 5184

The command halts the target process momentarily, audits its heap, outputs a summary report to the terminal window, and immediately resumes the process without interrupting user interaction.

Checking Command-Line Binaries Upon Exit

If you are developing or compiling command-line software on macOS, you can instruct leaks to monitor your executable throughout its entire lifecycle and produce an audit immediately before the process terminates:

leaks --atExit -- ./my_compiled_tool arg1 arg2

This syntax is invaluable for automated test suites, continuous integration jobs, and quick validation passes during local debugging.

Key Options and Diagnostic Modes in leaks

The table below summarizes the most practical options and flags available when executing leaks in macOS Terminal:

Option / Flag Example Syntax Description & Diagnostic Purpose
--atExit -- <cmd> leaks --atExit -- ./binary Monitors process execution and prints a leak report when the process exits cleanly.
-referenceTree sudo leaks -referenceTree 5184 Renders a tree diagram showing the reference hierarchy leading to unreferenced blocks.
-nocontext sudo leaks -nocontext 5184 Suppresses detailed hex dumps of leaked memory contents for cleaner output.
-outputGraph <path> sudo leaks 5184 -outputGraph /tmp/leak.memgraph Generates a full memory graph file (.memgraph) for deep inspection in Xcode or Instruments.
--groupByType sudo leaks 5184 --groupByType Aggregates leaked allocations by object class, struct, or allocation type.

Generating and Inspecting Memory Graphs (.memgraph)

For complex applications where multiple leaks interlock in retain cycles, saving an Apple memory graph allows offline forensics without keeping the app running:

  1. Generate the .memgraph archive:
    sudo leaks 5184 -outputGraph ~/Desktop/app_audit.memgraph
  2. Inspect the saved memory graph using companion command-line utilities such as malloc_history:
    malloc_history ~/Desktop/app_audit.memgraph -callTree
  3. Alternatively, double-click the .memgraph file on your desktop to open it inside the Xcode Memory Graph Debugger for interactive visual inspection of object retain paths.

Enabling MallocStackLogging for Detailed Backtraces

By default, leaks tells you what leaked, but not the exact source line where the allocation occurred. You can capture complete call stacks by running the application with MallocStackLogging enabled in your shell environment:

export MallocStackLogging=1
./my_application &
sudo leaks $!

With stack logging active, the leaks report annotates every leaked block with its exact invocation backtrace, pointing directly to the offending function and line number.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.