Gradle缓存迁移实战:彻底释放系统盘空间 系统盘空间释放之 Gradle 的默认缓存迁移先说说我自己的情况。上个月开发机 C 盘又飘红了排查一圈发现.gradle这个目录占了 40 多 G。干我们这行的都懂这玩意儿是 Android 和 Java 工程绕不过去的坎。刚开始以为删了就完事结果我顺手改了系统环境变量把 Gradle 缓存挪到了 D 盘又把原来那个 40G 的缓存目录按项目重新缓存预热了一遍。这一套折腾下来C 盘多出了 35G 可用空间而且之后新拉的项目再也没出现过“系统盘爆红”的警告。这篇内容就是把你可能也会遇到的 Gradle 缓存迁移、镜像配置、依赖损坏这几件事讲清楚。适合电脑 C 盘常年告急、公司强制用 Windows 开发、或者刚入坑 Gradle 还没搞懂缓存机制的朋友。我不会给你贴一堆看似专业的术语只会告诉你我是怎么排查、怎么改、怎么验证的以及那些踩过之后才明白的坑。1. Gradle 缓存为什么成了系统盘空间杀手1.1 GRADLE_USER_HOME 是这一切的源头Gradle 默认会在当前系统用户目录下创建一个.gradle文件夹至于这个文件夹具体在哪取决于GRADLE_USER_HOME环境变量的值如果不设置默认就是C:\Users\你的用户名\.gradle。这个目录在 Windows 上几乎必然是 C 盘在 macOS 上是/Users/你的用户名/.gradleLinux 则是/root/.gradle或/home/用户名/.gradle。这里要搞清楚一个概念Gradle 缓存不是只有依赖包那么简单。GRADLE_USER_HOME下通常有四个大头caches依赖 jar 包和元数据、wrapperGradle 发行版压缩包和解压后的完整运行时、daemonGradle 守护进程日志和注册信息、以及notifications、native之类的小杂项。一个持续开发了半年的项目caches占掉 8~15G 很正常如果同时维护三四个项目daemon日志也能积攒好几个 G再加上wrapper里存了多个 Gradle 版本一个版本就 500MB 左右三四个版本就是 2G 多。这就带来一个问题程序本身没多大但构建系统把运行产物和依赖都塞到了系统盘里。你可以打开系统和用户目录看下如果C:\Users\你的用户名\.gradle已经膨胀到 10G 以上那基本可以确定是 Gradle 在系统盘里养成了“全家桶”。1.2 为什么说它比 Maven 更吃空间Maven 的本地仓库默认在C:\Users\用户名\.m2\repository它只是单纯地存 jar 包。但 Gradle 不同它的缓存策略更激进会根据依赖的属性和来源分别存储而且同一个库的不同版本会全部保留不会自动清理旧版本。再加上 Gradle 还会缓存构建脚本编译产物、Kotlin DSL 脚本编译结果、注解处理器的生成代码这些统统塞进caches目录。实际测算下来同样一个 Spring Boot 项目Maven 依赖可能占 800MBGradle 缓存能到 2GB翻了一倍不止。更烦的是 Gradle 6.x 以后每个版本都会生成caches\modules-2、caches\transforms-3、caches\jars-9这一堆带版本号的子目录升级 Gradle 后旧目录不会自动删直接原地叠罗汉。1.3 清理 vs 迁移哪个才是根治方案很多人遇到 C 盘满的第一反应是手动删除.gradle下的缓存目录。这种办法确实能瞬间释放十多个 G但代价是下一次构建时 Gradle 需要重新下载所有依赖。要是公司网络快、镜像配置好也就算了如果是个小水管那重新拉依赖的时间够你喝三杯咖啡。所以真正划算的操作是把整个GRADLE_USER_HOME挪到其他盘让系统盘以后不再接收新产生的缓存数据。迁移之后就算缓存后续膨胀到 100G也跟 C 盘没有半毛钱关系。这才是一劳永逸的做法。2. 迁移方案的整体设计两种改法怎么选2.1 环境变量法 vs 软链接法迁移 Gradle 缓存有两种主流方案一是改系统环境变量GRADLE_USER_HOME二是用文件系统软链接。我不推荐新手上来就搞软链接虽然它看起来省事把.gradle移到 D 盘再在 C 盘用户目录下建一个指向 D 盘的符号链接但 Windows 上创建软链接需要管理员权限而且有些 IDE 或命令行工具对符号链接的识别并不总是正常。我在公司帮同事弄过好几次明明链接建好了但 Android Studio 缓存检查器总报错排查到最后才发现是链接类型搞错了目录链接要用/D参数。环境变量法就直白得多把GRADLE_USER_HOME指向D:\GradleUserHome\.gradle系统里所有调用 Gradle 的程序命令行、Android Studio、IDEA都会自动去新目录读写缓存。它的好处是零权限要求修改后重启 IDE 就生效而且非常透明谁都能看懂。两者对比下来我的建议是Windows 上用环境变量macOS/Linux 上可以用环境变量也方便用软链接反正看习惯。核心思路都是让 Gradle 别再往系统盘写数据。2.2 为什么新目录建议带.gradle子目录这里有个细节GRADLE_USER_HOME指向的目录Gradle 会直接在里面创建caches、wrapper这些子目录。如果你把变量直接设成D:\GradleUserHome那么下一次构建后 D 盘会出现D:\GradleUserHome\caches、D:\GradleUserHome\wrapper这样的目录结构。我习惯的方式是设成D:\GradleUserHome\.gradle这样一眼就能看出来这个目录是 Gradle 的“家目录”而且后面如果 D 盘还有 Maven 仓库D:\GradleUserHome\.m2那GradleUserHome根目录下面就是各种构建工具的家目录集合分区管理特别清晰找问题也好定位。2.3 迁移后 Gradle 还能找到旧缓存吗答案是不能。当GRADLE_USER_HOME改变后Gradle 会把它当成一个全新的空目录来初始化之前 C 盘里的所有缓存都会失效。所以迁移之后第一次构建项目会重新解析所有依赖本质上等于一次冷启动构建构建时间会明显变长。这一点必须在迁移前做好心理预期。想缓解的话可以把 C 盘旧缓存先完整复制到新目录这样 Gradle 在新目录里能直接复用原来的缓存内容省去重新下载的过程。复制大目录在 Windows 上如果你用资源管理器拖拽速度会非常痛苦建议用robocopy命令行工具带多线程参数几 GB 的目录几分钟就能搬完。3. 实操过程Windows 系统完整迁移步骤3.1 第一步先看当前 Gradle 家目录到底有多大管理员身份打开 PowerShell执行# 查看当前 GRADLE_USER_HOME 的值 echo $env:GRADLE_USER_HOME # 查看当前用户 .gradle 目录大小如果上面输出为空默认就是这个目录 {0:N2} GB -f ((Get-ChildItem -Path $env:USERPROFILE\.gradle -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1GB)如果GRADLE_USER_HOME有值那就以它为准。如果没有值默认就是C:\Users\你的用户名\.gradle。在我那次折腾中C 盘的.gradle大小是 42.7GB当时我一度怀疑统计错了因为项目才写到一半后来想想是三个项目和一个 Flutter 工程共享了这套缓存也就不奇怪了。3.2 第二步在目标盘创建新目录在 D 盘或空间充裕的分区新建一个目录比如D:\GradleUserHome\.gradle。这个目录可以提前建好也可以不建后面复制的时候会自动创建但建议还是手动建一下确保路径没有权限问题。注意目标分区尽量选择固态盘因为 Gradle 构建过程会大量频繁读写缓存机械硬盘的速度会成为瓶颈尤其是首次冷启动时构建速度可能会掉一半以上。如果 D 盘也是固态那就没这个问题。3.3 第三步复制旧缓存到新目录PowerShell 里执行 robocopy 命令# 把 C 盘旧 .gradle 目录完整复制到 D 盘新目录 robocopy $env:USERPROFILE\.gradle D:\GradleUserHome\.gradle /E /COPY:DAT /R:1 /W:1 /MT:16参数解释/E表示复制所有子目录包括空目录。/COPY:DAT表示复制数据、属性和时间戳不复制安全权限避免权限冲突。/R:1表示文件复制失败时只重试 1 次默认是 100 万次遇到权限问题会卡到天荒地老。/W:1表示重试等待 1 秒。/MT:16表示 16 线程并行复制大目录场景下能明显提速。robocopy 执行结果里会有个退出码0~7 都算正常复制不需要管只有 8 以上才是异常。copy完以后验证一下关键目录是否完整Test-Path D:\GradleUserHome\.gradle\wrapper Test-Path D:\GradleUserHome\.gradle\caches这两个路径存在就说明基本复制成功了。3.4 第四步设置 GRADLE_USER_HOME 环境变量按下Win R输入sysdm.cpl回车在“高级”选项卡里点击“环境变量”。在“用户变量”区域点击“新建”变量名GRADLE_USER_HOME变量值D:\GradleUserHome\.gradle这里我建议添加到“用户变量”而不是“系统变量”因为用户变量不需要管理员权限而且只对当前用户生效不会影响系统的其他账号。设置完记得一路点“确定”然后重启命令行窗口最好注销并重新登录一次系统确保所有进程都能拿到新变量。重启完后再次验证echo $env:GRADLE_USER_HOME如果输出的值是D:\GradleUserHome\.gradle那环境变量就生效了。3.5 第五步验证迁移是否正常随便找个老项目在命令行执行gradlew clean build --refresh-dependencies首次执行时会看到 Gradle 在新目录里初始化缓存下载依赖的过程会比较慢。等构建完成去D:\GradleUserHome\.gradle\caches下面看看如果出现了依赖 jar 包说明迁移成功。如果是 Android Studio 项目打开 IDE 后会自动触发 Gradle Sync这个过程中观察日志输出没有报“Could not find”或“Failed to create cache directory”之类的错误就说明没问题。3.6 第六步确认系统盘释放成功再执行第一步的大小统计命令C:\Users\你的用户名\.gradle应该已经不存在了或者只是一个残留的空壳。顺便看看系统盘剩余空间基本会多出相当于原缓存大小的可用空间。如果原来 C 盘的.gradle在复制完成后已经不想要了可以手动删掉注意删的时候如果有程序正在占用比如 Android Studio 还没关会提示无法删除。最好完全退出所有 IDE 和 Java 进程后再删。3.7 macOS / Linux 迁移要点macOS 和 Linux 操作逻辑完全一样区别在于目录路径和导出语句。# 假设旧缓存目录是 /Users/you/.gradle # 1. 创建新目录 mkdir -p /Volumes/Data/GradleUserHome/.gradle # 2. 复制缓存 cp -R /Users/you/.gradle/* /Volumes/Data/GradleUserHome/.gradle/ # 3. 设置环境变量写入 ~/.zshrc 或 ~/.bashrc echo export GRADLE_USER_HOME/Volumes/Data/GradleUserHome/.gradle ~/.zshrc # 4. 生效 source ~/.zshrc # 5. 验证 echo $GRADLE_USER_HOMELinux 上如果旧目录是/root/.gradle复制时注意权限用sudo cp -R会省很多事。4. 迁移后的配置优化镜像加速与缓存策略一起调4.1 顺手解决 Gradle 下载慢的问题迁移完成后第一次构建会触发大量依赖重新下载。如果公司服务器在国外或者网络对 Maven Central 和 Google Maven 访问极慢那这个首次构建的时间会让人怀疑人生。这也是热词里“gradle下载太慢 android studio”“gradle国内镜像站”反复被搜索的原因。解决方式是在项目的settings.gradle或build.gradle里配置镜像仓库。现在主流做法是直接配置阿里云镜像或者腾讯云镜像。以settings.gradle为例pluginManagement { repositories { maven { url https://maven.aliyun.com/repository/gradle-plugin } maven { url https://maven.aliyun.com/repository/google } maven { url https://maven.aliyun.com/repository/central } maven { url https://maven.aliyun.com/repository/public } gradlePluginPortal() } } dependencyResolutionManagement { repositories { maven { url https://maven.aliyun.com/repository/public } maven { url https://maven.aliyun.com/repository/google } maven { url https://maven.aliyun.com/repository/central } } }配置完以后同一份依赖的下载速度会有质的提升。我实测过同一份 Spring Boot 3.x 依赖默认源下要 20 分钟还经常超时换阿里云镜像后 3 分钟全下完。这个坑强烈建议提前避掉别等构建到一半突然报SocketTimeoutException才想起来换源。4.2 设置 daemon 日志不要无限膨胀Gradle daemon 运行日志默认写在GRADLE_USER_HOME\daemon下每次构建都会追加输出。时间一长这个目录也是吃硬盘的隐形大户一个项目跑 3 个月日志能到 1~2G。可以通过修改gradle.properties限制日志输出级别org.gradle.daemontrue org.gradle.consoleplain org.gradle.logging.levelinfoinfo级别比debug省不少空间而且日常排错也够用了。如果你觉得日志根本没用可以再把daemon目录定期清空D:\GradleUserHome\.gradle\daemon里的子目录可以放心删不影响任何项目。4.3 让 Android Studio 和 IDEA 也认新路径环境变量设置完毕后Android Studio 和 IDEA 通常会自动读取系统环境变量。但有一种情况例外IDE 内置的 Gradle JVM 环境可能和你命令行里用的 JVM 不一样。如果 IDE 里 Gradle 的 JVM 版本和项目要求的 Gradle 版本不匹配会出现“the projects gradle version 6.7.1 is incompatible with the gradle jvm version”的报错。这种情况下迁移只是解决了空间问题构建兼容性问题还是得另配。操作路径是File Settings Build Tools Gradle在Gradle JVM下拉框里选项目要求的 JDK 版本。Gradle 7.x 以上通常要求 JDK 11 或 17Gradle 6.7.1 则是 JDK 8 或 11注意对照一下。5. 常见问题与排查技巧实录5.1 迁移后构建报错Could not resolve all dependencies如果你迁移后立刻在旧项目里执行构建Gradle 可能因为旧缓存目录的元数据损坏或者新目录的依赖尚未下载完整报出各种“Could not resolve”错误。这时候我的排查步骤是先确认新目录的caches\modules-2\files-2.1下能不能找到报错库的名称。如果连目录都没有说明依赖还没下载到直接换镜像源再构建。如果目录存在但构建仍然报错大概率是之前的缓存元数据损坏执行gradlew clean然后删掉D:\GradleUserHome\.gradle\caches\modules-2\metadata-*目录强制 Gradle 重新解析元数据。这个操作是安全的只是重新生成解析清单不会删掉实际的 jar 包。最后再构建一次看看依赖能不能正常解析。5.2 Gradle 下载发行版一直超时SocketTimeoutException这个热词“could not install gradle distribution from hreason: java.net.sockettimeoute”对应的场景是Gradle Wrapper 需要下载某个特定版本的 Gradle 发行包默认从services.gradle.org下载网络差的时候必现超时。解决办法有两个方向。第一手动下载对应的 Gradle 发行包放到D:\GradleUserHome\.gradle\wrapper\dists下对应目录里第二改 Wrapper 的distributionUrl为国内镜像地址。我推荐第二种可以直接编辑gradle/wrapper/gradle-wrapper.propertiesdistributionUrlhttps\://mirrors.aliyun.com/gradle/gradle-8.5-bin.zip改完以后重新执行gradlewGradle 会去镜像地址下载速度明显上来了。5.3 gradlew.bat build 不下载 Gradle直接卡住“gradlew.bat build 不下载 gradle”这个热词也很典型。很多情况下不是没下载而是 Gradle daemon 启动失败后命令行没有任何提示。检查时先确认 Java 环境变量配好没有java -version gradlew --version如果java -version正常但gradlew --version卡住大概率是 Gradle daemon 在尝试连接之前残留的进程。直接杀掉所有 Gradle 相关进程taskkill /F /IM java.exe再重跑。如果还不行检查D:\GradleUserHome\.gradle\wrapper\dists里对应的压缩包是不是 0KB这通常意味着下载中断过删掉那个 0KB 文件重新跑就行。5.4 缓存损坏Gradles dependency cache may be corrupt热词里“gradles dependency cache may be corrupt (this sometimes occurs after a netw”对应的就是这种问题网络波动导致缓存目录里的部分文件写了一半就中断Gradle 下次构建时检测到不完整记录直接报缓存损坏。我的处理策略是先关闭所有正在运行的 Gradle 构建。打开D:\GradleUserHome\.gradle\caches\modules-2\files-2.1找到报错对应的库路径手动删除该库的完整目录。重新构建Gradle 会重新下载这个库。如果损坏的依赖太多一个个删太费劲也可以直接执行Remove-Item -Recurse -Force D:\GradleUserHome\.gradle\caches\modules-2让它整体重建。代价是全部依赖要重新下载但总比反复报错强。5.5 Flutter 项目报错You are applying Flutters main Gradle plugin imperatively热词“you are applying flutters main gradle plugin imperatively using the apply s”来自 Flutter 2.x 迁移到 3.x 后项目的 build.gradle 仍然使用旧式apply plugin写法的报错。表面看它和缓存迁移没什么关系但在迁移 Gradle 缓存后Flutter 项目如果构建失败很容易被误以为和缓存目录有关。实际处理方式是在android/settings.gradle里修改插件声明以 Flutter 新模板为准plugins { id dev.flutter.flutter-plugin-loader version 1.0.0 id com.android.application version 8.1.0 apply false // 其他插件 }然后在android/app/build.gradle顶部改成plugins { id com.android.application }这样就把旧的命令式插件应用改成了声明式避开了报错。这个过程和缓存迁移无关但会因为你刚折腾完 Gradle 而更容易被串联起来排查。5.6 Android Studio 配置 Gradle 的常见误区Android Studio 里配置 Gradle 时有一个很容易忽略的点IDE 内置的 JVM 和命令行 JAVA_HOME 不一致。迁移缓存后如果你在命令行里设置了JAVA_HOME指向 JDK 17但 Android Studio 里 Global Gradle Settings 的 Gradle JVM 还是 JDK 11那构建时会报版本兼容错误。我的习惯是让 IDE 和命令行统一 JDK 版本。在 Android Studio 的Settings Build Tools Gradle里把 Gradle JVM 选成和JAVA_HOME一样的 JDK这样就不会出现两边互相打架的问题。6. 迁移完成后的日常维护建议缓存迁走之后不等于一劳永逸。D:\GradleUserHome\.gradle一样会不断膨胀只是不再祸害系统盘而已。为了避免它哪天把 D 盘也塞满建议养成两个习惯。第一个习惯是定期清理旧版本缓存。Gradle 自带清理命令gradlew --stop然后手动删除D:\GradleUserHome\.gradle\caches\modules-2\files-2.1下那些超过半年没用的库目录。说白了就是看你最近还构建哪些项目不用的库删掉没任何影响最多就是下次构建慢一点。第二个习惯是控制本机 Gradle 版本数量。很多项目因为老旧原因绑定 Gradle 6.x 或 7.x每切换一个项目就要下载对应的 Gradle 发行版到wrapper\dists里。检查一下Get-ChildItem D:\GradleUserHome\.gradle\wrapper\dists -Directory如果发现超过三个版本且其中有些已经不再使用把对应目录删掉能释放好几个 G。我个人一直保留 Gradle 7.6.4 和 8.5 两个版本兼顾老项目和较新的项目再老的版本就通过改用 wrapper 动态控制。第三个建议是尽量把gradle.properties里的org.gradle.jvmargs合理设置不要盲目加大内存。有时候堆内存设到 4G一旦项目一多daemon 占用的内存会让你的开发机越来越卡。控制台观察一下如果构建很少发生 OutOfMemoryError就保持默认 2G 左右即可。7. 这些坑我都踩过给你提个醒迁移 Gradle 缓存这个操作本身不算复杂但有几个细节不注意到大概率会白折腾一趟。第一环境变量改完一定要注销或重启不要只关命令行窗口。很多程序特别是 IDE 和后台服务是启动的时候读取环境变量不会实时刷新。你只改完环境变量不重启 Android Studio它内部还是按 C 盘的路径去找缓存然后重建整个C:\Users\你\.gradle目录你之前复制的 D 盘新目录完全用不上系统盘也会继续被写占用。第二复制旧缓存时别开 Android Studio。如果你开着 IDE 复制caches目录有些 jar 文件正在被 Gradle daemon 占用robocopy 可能会报占用错误或者复制不完整。最安全的顺序是关闭 IDE → 关闭所有 Gradle daemon → 复制 → 设环境变量 → 重启 IDE。第三迁移完成后检查一下 Gradle daemon 状态。执行gradlew --status如果还有 daemon 进程跑着旧路径执行gradlew --stop全部停掉让它们下次以新路径重新启动。否则可能出现“明明缓存迁移了但构建时还在访问旧目录”的诡异现象。第四如果你是公司网络环境尽量和运维或者 IT 确认是否配了 Gradle 镜像仓库。如果公司内网有私有 Maven 仓库记得在settings.gradle里把公司仓库地址放在最前面避免依赖穿透到公网影响速度。最后再分享一个小技巧迁移后如果你用的是 IntelliJ IDEA可以在Settings Build Tools Gradle里把Gradle user home直接指定为D:\GradleUserHome\.gradle这样就算某些奇葩场景环境变量没生效IDEA 也会按这个路径走双保险。Android Studio 同理在 Global Gradle Settings 里设置即可。实测下来这个设置项比环境变量优先级更高能避免很多隐性冲突。