macOS 启动盘空间耗尽、可清除空间异常时的定位与清理
系统提示启动磁盘几乎已满,应用无法保存文件、更新失败,终端报 No space left on device;df -h / 的 Capacity 接近 100%,Finder 或“系统设置 > 通用 > 存储空间”却仍显示几十 GB 可用。也有人看到“系统数据”占用异常大,删掉大文件后空间没有立即回来。
APFS 把容器空间共享给多个卷,df 看到的是当前卷的可用空间,不一定等于容器真实余量;本地 Time Machine 快照、缓存和被进程占用的已删除文件还会形成“可清除空间”。因此要先分清:是真没有空间、被快照或缓存占用,还是被已删除但仍打开的文件占着。
先看卷、容器和快照三个层面:
df -h /
df -i /
diskutil info /
diskutil apfs list
diskutil apfs listSnapshots /
tmutil listlocalsnapshots /
tmutil listlocalsnapshotdates /
diskutil info / 里的 Container Free Space 比单个卷的 df 更能反映容器余量;diskutil apfs list 会列出每个卷的 Capacity Consumed 和快照;listSnapshots 中的 Purgeable: Yes 表示该快照可在空间紧张时回收。Time Machine 本地快照通常以 com.apple.TimeMachine. 开头,系统更新快照则以 com.apple.os.update- 开头,后者不要手动删除。
再按目录找大头,注意 APFS 的系统和数据卷分开挂载:
sudo du -xhd1 /System/Volumes/Data 2>/dev/null | sort -h
du -xhd1 ~ 2>/dev/null | sort -h
sudo find /System/Volumes/Data -xdev -type f -size +1G -print 2>/dev/null
sudo lsof -nP +L1
du -x 不跨文件系统,适合逐层下钻;先看一级目录,再进入异常大的目录继续。lsof +L1 列出链接数为零但仍被进程打开的文件,这类文件删除后空间不会释放,直到占用它的进程退出或重新打开日志。最后看日志和系统记录:
/usr/bin/log show --last 1h --style compact \
--predicate 'eventMessage CONTAINS[c] "no space left"'
ls -lhS /Library/Logs ~/Library/Logs 2>/dev/null | head -30
在 zsh 中 log 可能被同名内建命令占用,写 /usr/bin/log 可以避免参数错误。
~/Library/Caches、~/Library/Developer、~/Library/Containers、Docker 的磁盘镜像等。du 看不到,空间却未释放。df 看起来还有余量,容器实际已经接近上限。/private/var/log、/Library/Logs/DiagnosticReports、~/Library/Logs/DiagnosticReports。/private/var/vm 由系统管理,不应手动删除。先处理最安全、收益最大的部分:清空废纸篓,删除下载目录和项目目录中确认不再需要的大文件,把照片、视频和归档移到外置盘。删除前用 ls -lh 和 du -sh 确认目标,避免误删正在使用的数据。
处理 Time Machine 本地快照。优先让系统按需回收,确实需要立即释放时,用 thinlocalsnapshots 指定回收量而不是一次删光:
sudo tmutil thinlocalsnapshots / 20000000000 4
20000000000 约等于 20 GB,最后一个参数是回收紧迫程度。也可以先看日期,再按日期删除指定快照:
tmutil listlocalsnapshotdates /
sudo tmutil deletelocalsnapshots <快照日期>
删除快照会让对应时间点的本地恢复能力消失,但不会影响已完成的 Time Machine 备份。不要删除 com.apple.os.update- 开头的系统更新快照,也不要用 rm 直接删除快照。
清理缓存要按应用进行:退出应用后删除 ~/Library/Caches/<应用标识>,不要整目录粗暴清空;Docker 用 docker system prune,装了 Xcode 时可用 xcrun simctl delete unavailable 清理不可用模拟器,并在确认后删除 ~/Library/Developer/Xcode/DerivedData。iOS 备份在 Finder 的“管理备份”中删除,照片图库用“照片”应用提供的优化或导出功能处理。
如果怀疑是已删除但仍打开的文件,按 lsof +L1 的 PID 找到进程,优先用 launchctl kickstart -k 或正常重启服务让它释放文件;不要直接 kill -9 正在写数据的进程。重启系统也能释放大部分临时文件和可清除空间,但重启前应保存工作。
日志和诊断报告只删除明确可再生的旧文件,保留最近的崩溃记录用于排障。统一日志不要用 rm 删除,必要时用 /usr/bin/log show 导出后再由系统轮转;/private/var/vm 和 /System/Volumes/Update 属于系统管理区域,不要手动清理。
如果 df 与 Finder 长期矛盾,或 diskutil apfs list 显示容器被其他卷占用,先用“磁盘工具”的“急救”检查文件系统,再决定是否删除不再需要的 APFS 卷。任何删除卷、抹掉磁盘的操作都必须先备份。清理后再次用 df -h /、diskutil apfs list 和 tmutil listlocalsnapshots / 复验,并保留至少 15% 到 20% 的余量,避免更新和快照再次把磁盘填满。
合上页面,先回答,再展开对照。
df 却接近满,这两个结果矛盾吗?df 反映当前卷的可用块。用 diskutil info / 看容器余量,用 tmutil listlocalsnapshots / 和 lsof +L1 判断空间被什么占着。sudo tmutil thinlocalsnapshots / <字节数> 4,或按 tmutil listlocalsnapshotdates / 的结果删除指定日期的 Time Machine 本地快照。com.apple.os.update- 开头的系统更新快照不能删。sudo lsof -nP +L1 找已删除但仍被进程打开的文件,重启对应服务或系统释放;再用 diskutil apfs list 检查是否是其他 APFS 卷或快照占用,并确认 du 统计的是数据卷而不是系统卷。
小程序版
微信扫码,随时查命令