"Using a lot of memory" and "leaking memory" are different problems. A leak is a process whose RSS rises steadily and never falls, including when the machine is idle. One snapshot can't tell you that — you need two, taken apart.
1. Who's biggest right now
$ clai list processes sorted by memory usage→ ps -eo pid,comm,rss,%mem --sort=-rss | head -4 PID COMMAND RSS %MEM 218979 firefox 2089376 3.1 269458 verba 1257196 1.9 727108 telegram 1249824 1.9
RSS is in kilobytes and is the number that matters: physical memory actually resident. This is your list of suspects, not your answer.
2. Watch one process over time
$ clai sample memory of pid 269458 every 10 seconds, 6 times→ pidstat -r -p 269458 10 6
This is the actual test. Rising RSS across all six samples while load is flat means a leak. Rising then flattening means a cache filling up, which is normal and will stop.
3. Cheap sampling without extra packages
$ clai log this process's memory every minute to a file→ while sleep 60; do printf '%s %s\n' "$(date +%T)" "$(grep VmRSS /proc/269458/status)"; done | tee mem.logVmRSS: 1257196 kB
pidstat lives in the sysstat package and isn't always installed. /proc/<pid>/status always is. Leave it running for an hour and the shape of the answer will be obvious.
4. Where inside the process the memory went
$ clai show the memory map of pid 269458 sorted by size→ sudo pmap -x 269458 | sort -k3 -rn | head
A single anonymous mapping that grows between two runs of pmap is the heap. Many small mappings that keep multiplying usually means leaked thread stacks or unclosed mmap'd files.
5. Rule out the file cache first
$ clai show memory usage excluding cache and buffers→ free -h total used free shared buff/cache availableMem: 62Gi 18Gi 2.1Gi 1.2Gi 42Gi 43Gi
Look at available, not free. Linux deliberately fills unused RAM with page cache and gives it back on demand. "Only 2 GB free" with 43 GB available is a healthy system, not a leak.
6. Confirm it's the process, not the machine
$ clai check whether the kernel has been killing processes for memory→ sudo dmesg -T | grep -i 'killed process'
If the OOM killer has fired, the kernel names the process it chose and its memory at the time. That's the strongest confirmation you'll get, written down for you already.
Gotchas
- RSS double-counts shared memory. Two processes sharing a library both report its pages. For per-process truth use PSS from
smemor/proc/<pid>/smaps_rollup. - A restart is a workaround, not a diagnosis. It resets the graph and hides the evidence. Sample first, restart second.
- Container limits are invisible from inside. A process in a container sees the host's total memory in
free; the real ceiling is in/sys/fs/cgroup/memory.max.
Related questions
How much growth is a leak? Any sustained upward slope with flat workload. A process that gains 50 MB an hour and never gives it back will hit the OOM killer eventually, no matter how much RAM you add.
Is high memory usage on Linux bad? Not by itself. Unused RAM is wasted RAM — the kernel uses it for cache and reclaims it under pressure. Watch available and swap activity instead.
Which tool finds the leaking line of code? Valgrind (--leak-check=full) for C and C++, or your language's own heap profiler. The commands here find which process; fixing it is a different tool.
See also
- "Who's eating my CPU right now?" — system monitoring in plain English
- Kill the process on port 8080 — and other things you always Google
- df says the disk is full, du says it isn't
Say what you want to measure, and CliAI writes the pidstat invocation you'd otherwise look up. Install it in one line.