About | ACP | Buy | Industry Watch | Learning Curve | News | Products | Search | Substack
Home » Learning Curve » Developers Workshop

Leaks Like a Sieve

Was Woz right? After all, memory management is simple - isn't it?

Get It

Try It

Apple's macOS code leaks like a sieve. Lots of it does. Not all of it - lots of it. Leaks bad.

Not so terribly far back in the mists of time, we took our own collection, the ACP - including 70+ Cocoa utilities - and ran them through leak tests.

leaks(1)          BSD General Commands Manual         leaks(1)


leaks - Search a process's memory for unreferenced malloc buffers


leaks identifies leaked memory - memory that the application has allocated, but has been lost and cannot be freed. Specifically, leaks examines a specified process's memory for values that may be pointers to malloc-allocated buffers. Any buffer reachable from a pointer in writable global memory (e.g., __DATA segments), a register, or on the stack is assumed to be memory in use. Any buffer reachable from a pointer in a reachable malloc-allocated buffer is also assumed to be in use. The buffers which are not reachable are leaks; the buffers could never be freed because no pointer exists in memory to the buffer, and thus free() could never be called for these buffers. Such buffers waste memory; removing them can reduce swapping and memory usage. Leaks are particularly dangerous for long-running programs, for eventually the leaks could fill memory and cause the application to crash.

There have been other tools available of course, but /usr/bin/leaks is the yardstick.

Our own leaks project took well over half a year to complete - getting rid of all leaks until /usr/bin/leaks turned up nada on each and every one. Some leaks were recognisable after a time. Others were more difficult to figure out. But we got them all.

The rules of memory management in Objective-C are eminently straightforward. They're 'black and white'. They should be learned. Unfortunately, Apple caved in there for a while and implemented automatic garbage collection. So that programmers who were too lame to learn elementary memory management fundamentals didn't have to learn after all. (Then of course they outlawed automatic garbage collection some time later, so programs built with it suddenly refused to run. Oh well. Typical Apple.)

A bit of explanation here. It's not always your own code that's the culprit behind a leak. In our case, it rarely was. The culprit is most often the supporting system frameworks supplied by Apple. These Apple frameworks are almost always the culprits.

So the leak hunters start out on a lugubrious process to find alternative ways to achieve the same thing that's already in their own code, but doing in a different way, invoking different APIs. And, yes, it can be done. It often takes time, patience, and ingenuity. But it can be done.

Unfortunately, the conscientiousness and pride that people can take in their own products is not necessarily a sentiment shared by corporate rank and file. Steve Wozniak caused quite the stir when he said that Apple code ranked easily as the worst he'd seen.

So what happens, if you completely clean your code of all leaks - all of them - and run them all through /usr/bin/leaks, and they all get perfect report cards... and then Apple come out with a new version of their OS and /usr/bin/leaks suddenly reports new leaks all over the place? Seriously now: who's the odd man out? You got it.

But that wonderful experience was back in the says of Sierra and High Sierra. One such experience is more than enough. Now they've gifted us with Dark Mode Mojave and the unstable Catalina, and the situation is - perhaps not unexpectedly - even worse. Frankly, there's no point in worrying about leaks if Apple's programmers don't seem to care themselves.

Of course an OS should be free of leaks. Of course it should. But Apple's OS is not. Apple's OS is at the other end of the spectrum. The needle's pinned at the wrong end.

Not all modules suffer, to be honest. But if the core frameworks leak, then almost all software will leak, and Apple's core frameworks leak a lot.

But let's take a look at Apple's own code, let's take a look at Apple software, running on Apple frameworks, and see what we find. There's a lot of variation here. Apple applications are of course maintained by different groups, so results will vary - and that is the key. Some of these modules are well sealed, as reported by their own version of /usr/bin/leaks, and some are not. You'll quickly discern patterns.

To run leaks on any program you have on your computer, just go to a command line and type in 'leaks' plus the name (eg Mail, Safari) of the program you want to audit.

Activity Monitor

Activity Monitor is a complex application. There's a lot going on there. You don't need to do much other than start it up. Yet Activity Monitor comes with a clean bill of health.

Process:         Activity Monitor [21817]
Load Address:    0x107429000
Identifier:      Activity Monitor
Version:         ???
Code Type:       X86-64
Parent Process:  ??? [1]

Analysis Tool:   /usr/bin/leaks

Process 21817: 49730 nodes malloced for 7812 KB
Process 21817: 0 leaks for 0 total leaked bytes.

App Store

App Store is an app you'd expect to leak a lot. You'd be right.

Process:         App Store [21824]
Load Address:    0x10873d000
Identifier:      com.apple.AppStore
Code Type:       X86-64
Parent Process:  ??? [1]

Analysis Tool:   /usr/bin/leaks

Physical footprint:         119.3M
Physical footprint (peak):  182.3M

Process 21824: 370882 nodes malloced for 147252 KB
Process 21824: 93 leaks for 7024 total leaked bytes.

The leaks report for App Store is 168 lines long.

Disk Utility

Disk Utility is a crucial app. You need it to not leak. And for the most part it doesn't.

Process:         Disk Utility [21857]
Load Address:    0x101f9d000
Identifier:      com.apple.DiskUtility
Code Type:       X86-64
Parent Process:  ??? [1]

Analysis Tool:   /usr/bin/leaks

Physical footprint:         33.3M
Physical footprint (peak):  37.8M

Process 21857: 61129 nodes malloced for 21170 KB
Process 21857: 1 leak for 64 total leaked bytes.


Your Dock is the most central part of your user experience. Together with Finder, it replaces NeXT's old 'Workspace'. Your Dock is always running. You really need your Dock to not leak memory. Unfortunately, it does - it leaks a lot.

Process:         Dock [19762]
Load Address:    0x107e70000
Identifier:      com.apple.dock
Code Type:       X86-64
Parent Process:  ??? [1]

Analysis Tool:   /usr/bin/leaks

Physical footprint:         17.8M
Physical footprint (peak):  31.6M

Process 19762: 50249 nodes malloced for 46063 KB
Process 19762: 198 leaks for 21104 total leaked bytes.


You'd expect Mail to leak a lot. And maybe it does with extended use. But not on this test run.

Process:         Mail [21089]
Load Address:    0x1065a7000
Identifier:      com.apple.mail
Code Type:       X86-64
Parent Process:  ??? [1]

Analysis Tool:   /usr/bin/leaks

Physical footprint:         47.2M
Physical footprint (peak):  49.3M

Process 21089: 174023 nodes malloced for 35667 KB
Process 21089: 2 leaks for 96 total leaked bytes.


A real workhorse utility. It's perhaps not crucial that it not leak. But it didn't leak at all on this test run.

Process:         Preview [21832]
Load Address:    0x10d2f1000
Identifier:      com.apple.Preview
Code Type:       X86-64
Parent Process:  ??? [1]

Analysis Tool:   /usr/bin/leaks

Physical footprint:         24.6M
Physical footprint (peak):  25.2M

Process 21832: 77149 nodes malloced for 11700 KB
Process 21832: 0 leaks for 0 total leaked bytes.

QuickTime Player

Process:         QuickTime Player [21848]
Load Address:    0x100821000
Identifier:      com.apple.QuickTimePlayerX
Code Type:       X86-64
Parent Process:  ??? [1]

Analysis Tool:   /usr/bin/leaks

Physical footprint:         33.0M
Physical footprint (peak):  33.3M

Process 21848: 71743 nodes malloced for 16728 KB
Process 21848: 13 leaks for 736 total leaked bytes.


Ah. Here we go. The app that makes all the others look bad. Safari has been accused of a lot of things in the past, and mostly justifiably. And don't even begin to look at the filesystem havoc.

Process:         Safari [8697]
Load Address:    0x105317000
Identifier:      com.apple.Safari
Code Type:       X86-64
Parent Process:  ??? [1]

Analysis Tool:   /usr/bin/leaks

Physical footprint:         258.5M
Physical footprint (peak):  292.5M

Process 8697: 993923 nodes malloced for 288649 KB
Process 8697: 19019 leaks for 3574928 total leaked bytes.

Safari is leaking over three and one half MB. Its leaks report is 22,610 lines long.


This was a surprise.

Process:         Xcode [21072]
Load Address:    0x103413000
Identifier:      com.apple.dt.Xcode
Code Type:       X86-64
Parent Process:  ??? [1]

Analysis Tool:   /usr/bin/leaks

Physical footprint:         78.1M
Physical footprint (peak):  78.2M

Process 21072: 366244 nodes malloced for 33983 KB
Process 21072: 0 leaks for 0 total leaked bytes.

About Rixstep

Stockholm/London-based Rixstep are a constellation of programmers and support staff from Radsoft Laboratories who tired of Windows vulnerabilities, Linux driver issues, and cursing x86 hardware all day long. Rixstep have many years of experience behind their efforts, with teaching and consulting credentials from the likes of British Aerospace, General Electric, Lockheed Martin, Lloyds TSB, SAAB Defence Systems, British Broadcasting Corporation, Barclays Bank, IBM, Microsoft, and Sony/Ericsson.

Rixstep and Radsoft products are or have been in use by Sweden's Royal Mail, Sony/Ericsson, the US Department of Defense, the offices of the US Supreme Court, the Government of Western Australia, the German Federal Police, Verizon Wireless, Los Alamos National Laboratory, Microsoft Corporation, the New York Times, Apple Inc, Oxford University, and hundreds of research institutes around the globe. See here.

All Content and Software Copyright © Rixstep. All Rights Reserved.

John Cattelin
Media Contact
ACP/Xfile licences
About | ACP | Buy | Industry Watch | Learning Curve | News | Products | Search | Substack
Copyright © Rixstep. All rights reserved.