go clean -modcache 仅清理模块缓存,不处理构建产物($gopath/pkg 非 mod/ 子目录)和未引用 module;安全清理需用 go clean -cache -modcache,手动删前须确认 go111module=off 状态,并动态获取 gocache 路径。

为什么 go clean -modcache 不能直接删掉所有冗余?
因为 Go 的“冗余”分三类:模块缓存、构建产物、本地 GOPATH 副本,go clean -modcache 只清第一类。你执行完发现 $GOPATH/pkg 还占几个 GB,build/ 目录里一堆 __debug_bin,甚至 go mod download 后残留的未引用 module 也还在磁盘上——这些都不是 go clean 管的。
怎么安全清理 $GOPATH/pkg 和 $GOCACHE?
这两处是 Go 构建和依赖缓存的核心路径,直接 rm -rf 有风险:如果当前有正在编译的项目,可能触发 invalid operation: cannot import "xxx" (no metadata);某些私有模块认证信息(如 netrc)也可能被误删导致后续 go get 失败。
- 优先用官方命令:
go clean -cache -modcache(清$GOCACHE和$GOPATH/pkg/mod) - 手动清理
$GOPATH/pkg下非mod/的子目录前,先确认没人在用GO111MODULE=off模式:go env GOPATH查路径,再find $GOPATH/pkg -maxdepth 2 -type d -name "*_" -o -name "obj" | xargs rm -rf -
$GOCACHE可设为内存盘(Linuxtmpfs)避免反复 IO,但脚本里别硬编码路径,始终用go env GOCACHE动态获取
如何识别并删除未被任何 go.mod 引用的本地 module?
Go 不会自动卸载已下载但不再 require 的 module,尤其在频繁切换分支或试用实验性库后,$GOPATH/pkg/mod/cache/download 里会堆积大量 hash 命名的压缩包和解压目录。
在 Golang 中使用 samber/hot 进行内存缓存,支持 LRU、LFU、TinyLFU、W‑TinyLFU、S3FIFO、ARC、TwoQueue、SIEVE、FIFO 等淘汰算法,提供 TTL、缓存加载器及分片功能。
- 用
go list -m -f '{{.Path}} {{.Version}}' all 2>/dev/null | sort | uniq获取当前所有 active module 列表 - 对比
ls $GOPATH/pkg/mod/cache/download输出,对不在列表里的域名目录(如github.com/someuser/somelib/@v/)可安全清理 - 更稳妥的做法是:先
go mod graph | awk '{print $1}' | sort -u抽出所有直接/间接依赖,再过滤 cache 目录 —— 注意go mod graph需在 module 根目录运行,且不包含 replace 或 exclude 规则中的路径
写一个最小可用的清理脚本要注意什么?
别一上来就 rm -rf $HOME/go。真实环境里常有人把 $GOPATH 设成 ~/go,但又把个人工具(如 gopls、dlv)装在 bin/ 下,删了就丢命令。
- 脚本开头必须检测
go version≥ 1.16(go clean -modcache在此版本才稳定支持) - 对每个要删的路径,先
echo出来让用户确认,加-y参数才跳过(例如:if [[ "$1" != "-y" ]]; then read -p "Delete $GOCACHE? [y/N] " -n 1 -r; echo; [[ $REPLY =~ ^[Yy]$ ]] || exit 0; fi) - 避免跨平台陷阱:Windows 上
$GOCACHE默认在%LocalAppData%\go-build,不能简单套用 Unix 路径逻辑
真正麻烦的是 replace 路径和 vendor 目录共存时的判断——脚本没法自动知道某个本地 replace ./localpkg 是临时调试还是长期依赖,这类得人工介入。留个 ./clean-go-env.sh --dry-run 模式,比直接删更实际。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










