The quickest answer is to sort Activity Monitor by Memory and read the top rows. The catch is that one app often shows up as dozens of rows, so the biggest single row is rarely the biggest app. The fix is to add the rows up per app. Here is how I do it in Terminal, and how to tell whether the number is a problem at all.
How do I see memory use per app instead of per process?
Browsers and Electron apps run many helper processes. Activity Monitor shows each helper on its own line, with names like Google Chrome Helper (Renderer). This one-liner groups every process by the .app it lives in and adds up resident memory:
ps -axo rss=,command= | awk '{ if (match($0, /[^\/]+\.app/)) { a=substr($0,RSTART,RLENGTH); m[a]+=$1 } } END { for (k in m) printf "%8.0f MB %s\n", m[k]/1024, k }' | sort -rn | head
It prints something like this, with your own apps and numbers:
4210 MB Google Chrome.app
1650 MB Slack.app
980 MB Xcode.app
Two caveats. rss is resident memory, and shared pages get counted once per process that maps them, so the totals run a little high. And anything that isn't inside a .app bundle, like node or docker, is skipped by this command. For those, use the next section.
How do I find the biggest single processes?
top can do it without leaving the terminal:
top -o mem -l 1 -n 10 -stats pid,command,mem
-l 1 takes one sample and exits, -o mem sorts by memory, and -n 10 limits it to ten rows. This is where command-line tools like node, python or java show up, which the .app grouping above misses.
If you have a pile of node processes, add them up by name:
ps -axo rss=,comm= | awk '{ n=$2; sub(/.*\//,"",n); m[n]+=$1 } END { for (k in m) printf "%8.0f MB %s\n", m[k]/1024, k }' | sort -rn | head
That is the command that first showed me how much a few forgotten dev servers were holding.
Is high memory use actually a problem on a Mac?
Not by itself. macOS uses spare RAM for file caches on purpose, so "almost all of it is used" is normal. What matters is pressure: whether the system is having to compress memory or swap to disk to keep up.
memory_pressure | tail -n 1
The last line reports the percentage of memory free, and the output above it says whether the system is under pressure. Activity Monitor's Memory tab shows the same thing as the green, yellow or red Memory Pressure graph. As a rule of thumb:
- Green: nothing to do, even if the used number looks scary.
- Yellow: the system is compressing memory. Worth finding the biggest app.
- Red: it is swapping heavily. Quit something now.
You can also look at swap directly:
sysctl vm.swapusage
Swap that keeps growing while you work is a better sign of a leak than a high used-memory number is.
How do I tell a leak from normal use?
A single reading can't tell you. A leak is memory that keeps climbing in one app while you do the same thing. Run the per-app command twice, thirty minutes apart, and compare. If one app gained a couple of gigabytes and the rest are flat, that is your culprit.
On the Mac I work on, that app was usually a long-running dev server or an Electron app I had left open for days. Quitting and reopening it gave the memory back.
Can I quit the app safely?
Use the normal quit first, with Cmd-Q, and give it a few seconds. Only use force quit if it hangs, because you can lose unsaved work. From the terminal:
osascript -e 'quit app "Slack"'
That asks the app to quit the same way Cmd-Q does, so it gets a chance to save. kill -9 does not, so keep it for last.
Is there a way to not do this by hand?
I got tired of pasting that awk line, so I built the answer into Binnacle, the Mac menu bar monitor I make. Its Memory page lists memory by app with helpers folded in, so Chrome is one row. It keeps 30 days of per-app history, so you can look back at what grew yesterday. It has an alert that fires when an app's memory has grown by 2 GB in 30 minutes, at most once an hour per app. Quitting asks you to confirm first. It is free for 14 days and $9 once after that, and the menu bar readouts stay free after the trial: https://binnacle.shafer.llc?utm_source=blog
You don't need it for this, though. The three commands above answer the question on any Mac:
pswithawkto total memory per app.top -o memfor the biggest single processes.memory_pressureto decide whether any of it matters.
If pressure is green, close the terminal and get on with your day. If it is yellow or red, the first line of the per-app list is where to start.