debugMajor
Diagnosing macOS memory exhaustion with JetsamEvent reports — kill reason distinguishes real OOM from benign caps
Viewed 0 times
JetsamEventvm-compressor-space-shortagejetsam OOM macosmac freeze force rebootmemory compressor kernel_taskswapusage high water markuserspace_watchdog_timeoutbug_type 298
Error Messages
Problem
A macOS machine intermittently freezes, becomes unresponsive, or has to be force-powered-off, and the user reports it as a crash. Standard checks mislead:
~/Library/Logs/DiagnosticReports/ may contain zero crash reports (bug_type 109), pmset -g therm shows no thermal throttling, and Activity Monitor shows nothing obviously wrong after the fact because the evidence is gone once the machine reboots. Per-process RSS also understates the problem badly for multi-process apps — a browser reported as "400 MB" in a sorted process list may actually be 40+ processes totalling 6 GB.Solution
The authoritative evidence lives in the SYSTEM diagnostic directory, not the user one, and the kill reason is what separates a real out-of-memory event from routine housekeeping.
ls /Library/Logs/DiagnosticReports/ ~/Library/Logs/DiagnosticReports/
Key bug_type values: 109 = crash, 309 = hang/spin, 298 = JetsamEvent (OOM kill), 409 = watchdog timeout, 115 = ResetCounter (boot fault record).
ls /Library/Logs/DiagnosticReports/JetsamEvent-*.ips
-
-
A single report can contain thousands of kills. Count them by reason rather than counting reports.
ps -Ao rss,command | grep -i "[B]rave" | awk '{s+=$1; n++} END {printf "%d procs, %.1f GB\n", n, s/1024/1024}'
- Count and classify reports by bug_type across both directories:
ls /Library/Logs/DiagnosticReports/ ~/Library/Logs/DiagnosticReports/
Key bug_type values: 109 = crash, 309 = hang/spin, 298 = JetsamEvent (OOM kill), 409 = watchdog timeout, 115 = ResetCounter (boot fault record).
- Read the JetsamEvent reports. They are JSON:
ls /Library/Logs/DiagnosticReports/JetsamEvent-*.ips
- THE CRITICAL DISTINCTION — inspect the per-kill
reasonfield:
-
per-process-limit / highwater: a single process hit its own memory cap. BENIGN and routine; macOS does this constantly. Do NOT report it as a system OOM.-
vm-compressor-space-shortage: the kernel ran out of room to compress and began killing processes to survive. This is a REAL system-wide OOM event.A single report can contain thousands of kills. Count them by reason rather than counting reports.
- Identify the culprit via the
largestProcessfield plus each victim'srpages(resident pages, multiply by 16384 on Apple Silicon for bytes). The largest resident process at the moment of the event is usually the cause, not the victim — victims are typically system daemons being sacrificed.
- Correlate the timeline. A genuine exhaustion cascade looks like: several JetsamEvents minutes apart, then a WindowServer
userspace_watchdog_timeout(bug_type 409) when the UI freezes, then a ResetCounter report. Check the ResetCounter forBoot faults:— values likebtn_rst,finger_reset force_offare documentary proof the user physically held the power button, i.e. the machine locked up hard.
- Measure multi-process apps by SUMMING, never by reading a sorted per-process list:
ps -Ao rss,command | grep -i "[B]rave" | awk '{s+=$1; n++} END {printf "%d procs, %.1f GB\n", n, s/1024/1024}'
- Read live pressure correctly.
sysctl vm.swapusageshows both used and total; total GROWS under pressure (macOS adds 1 GB swapfiles) and is high-water-mark — it does NOT shrink while the system runs, only on reboot. So high swap on an idle system is residue, not current load. Cross-check with the compressor viavm_statandmemory_pressure.
Why
macOS masks memory exhaustion. The kernel's jetsam mechanism kills processes to avoid a kernel panic, so from the user's perspective apps silently vanish or the UI wedges rather than producing a crash log — which is why a machine can have a severe memory problem and zero bug_type 109 reports. The memory compressor compounds the confusion: heavy compression shows up as
kernel_task burning CPU, which is easily misdiagnosed as thermal throttling when it is actually memory work. And because jetsam reports go to the system directory while application crashes go to the user directory, anyone checking only ~/Library/Logs/DiagnosticReports/ sees a clean machine.Gotchas
- JetsamEvent reports go to /Library/Logs/DiagnosticReports/ (system), NOT ~/Library/Logs/DiagnosticReports/ (user). Checking only the user path shows a falsely clean machine.
highwater/per-process-limitkills are routine and must not be reported as OOM. Onlyvm-compressor-space-shortageindicates real system-wide exhaustion.- Swap total grows under pressure and never shrinks while running — it is a high-water mark. High swap on an idle system is residue from an earlier peak, and only a reboot clears it.
kernel_taskat high CPU during memory pressure is the compressor, not thermal throttling. Confirm withpmset -g therm, which will show zero thermal events.- Sorted per-process RSS lists systematically understate Chromium-based browsers and Electron apps. Always sum across the whole process family.
system_profiler SPPowerDataTypereturns a brokenFull Charge Capacity (mAh): 100on Apple Silicon. Useioreg -r -c AppleSmartBatteryand compute NominalChargeCapacity / DesignCapacity instead.- When running a parallel audit, the audit's own agents can spike load average and swap. Always take a clean baseline after they exit, and never report self-inflicted load as a pre-existing user problem.
Context
Investigating unexplained macOS freezes, forced reboots, apps being killed in the background, or general sluggishness — especially on 16 GB machines running a heavy browser alongside VMs, containers, or multiple agent/dev sessions.
Revisions (0)
No revisions yet.