算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
macos-load-doctor【设计与创意】Diagnoses macOS system-level slowness, heat and fleet-wide timeouts: high load average, leaked per-session child processes (MCP servers, helpers), fork storms, busy loops. Use when the Mac feels slow or hot, fans spin up, or everything times out at once (电脑发烫/卡顿/负载高/全部超时). Not for single-app bugs, network slowness (use tunnel-doctor), launchd watchdo…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Find what is making the Mac slow or hot, attribute it to an owner, and act within the shared-machine boundary. The skill's job is a correct, evidence-backed attribution — not process cleanup.
A fleet-wide symptom is an environment problem until proven otherwise. When independent apps, hooks or agents all start timing out or crawling at the same time, none of them is the suspect — something is starving them all. Check the machine first; debug individuals only after the machine reads clean.
sysctl -n vm.loadavg; uptime
Expected: three numbers, e.g. { 3.12 4.01 5.20 }. Read against the core
count, not an absolute: single digits are calm on a modern Mac; tens are busy;
hundreds mean the run queue is many times oversubscribed and everything on
the machine is a victim — hooks time out, keystrokes lag, pushes stall. A
load in the hundreds with no obvious culprit in the CPU column usually means
hundreds of small processes, not one big one.
LOAD_DOCTOR_DIR='<absolute directory containing this SKILL.md>'
bash "$LOAD_DOCTOR_DIR/scripts/load_census.sh"
Resolve that directory from the loaded Skill entry; the caller's project directory is not the Skill directory. The census readings answer different questions:
Trace the parent chain of the suspect until it ends at something ownable:
ps -o pid,ppid,etime,command -p <pid> # then repeat on its PPID
launchctl list | awk '$2 != "-" && $2 != "0"' # jobs with abnormal last-exit codes
The launchctl filter also prints its header line, and many system daemons
sit at status -9 (SIGKILL) permanently — that is routine noise, not a crash
loop. The respawn-loop signal is a job whose PID keeps changing between
runs, not any single status value.
Attribution determines which product/session owns it, whether it is supposed to be long-lived (a daemon) or short-lived (a helper that forgot to die), and who is allowed to stop it.
| Shape | Signature | Typical cause |
|---|---|---|
| Leak candidate | retained child count grows after comparable work finishes, or helpers outlive their documented lifecycle | missing cleanup; confirm workload and lifecycle before calling it a leak |
| Fan-out / pool | many children correlate with active sessions or a stable configured pool | per-thread ownership can be expensive without being a leak |
| Storm | many processes with seconds-short etimes, high fork rate | unthrottled loop (test replay, batch scan, retry without backoff) |
| Busy loop | one process at ~100% with days of cumulative time | app polling without sleep |
| Cascade | load high but suspects scattered | a system service amplifying each new process (security scans, file-sync, Spotlight) |
The fix is different for each: a confirmed leak wants the spawner fixed or restarted, a storm wants throttling at the loop, a busy loop wants the app relaunched or its scan disabled, a cascade wants fewer new processes, not faster ones.
On a shared machine, diagnosis is read-only; remediation has an owner.
sysctl -n vm.loadavg and the census, then exercise the user's original
capability through its actual consumer. Disabling a service can relieve load
while removing that capability: report mitigation until it works again.
Before a configuration reload, establish whether its scope includes other
threads/services. Compare target and non-target helpers before/after; an
unchanged master PID does not prove that other helpers were unaffected.For a memory complaint, measure pressure and activity alongside process counts:
sysctl vm.swapusage
vm_stat -c 4 2
ps -axo pid,ppid,rss,command
Read the page size printed by vm_stat; its first row is cumulative and later
rows show interval activity. Existing swap allocation does not establish current
thrashing: inspect swap-in/out activity over the sampled window and report that
window. RSS totals can count shared resident pages repeatedly and are not unique
physical memory. For a suspect, use vmmap -summary <pid> to distinguish its
reported physical footprint from RSS; retain separately reported GPU/IOKit
allocations instead of silently adding unlike counters. A large allocation or
compressed-memory snapshot alone does not identify retained objects or a leak.
Apple's memory guide defines memory pressure using free memory, swap rate, wired memory and cached files. The executing agent interprets those signals and the observed workload; the census does not mechanically classify a leak.
Worked cases with real probe outputs live in references/incident-playbook.md — read it when the census shows something you have not seen before, or when you need a precedent for the report you are about to write.
launchctl list shows a non-zero last-exit code and a PID that keeps
changing.ps -Ao pid= snapshots a few seconds
apart, count the PIDs that appear only in the second
(comm -13 <(sort old.txt) <(sort new.txt) | wc -l, divided by the interval).
Dozens per second is a storm; a few is normal churn.