拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Gradle 9.4 + Java 26 多模块构建性能优化实战:从23分钟到5秒

第一次接手一个接近两百个模块的 Java 服务端项目时光是执行一条./gradlew :core:test --tests *.UserServiceTest就得等 8 分多钟。后来靠 Gradle 9.4 加上 Java 26 的组合做了一轮彻底调优同等条件下单测启动基本稳定在 5 秒左右全量构建也从 20 多分钟压进了几分钟。这个量级的变化不是靠某一个开关就能实现的而是整个构建链路的系统工程。这篇文章就基于这套实战配置展开适合正在被大型 Java/Gradle 项目构建速度折磨的朋友尤其是多模块项目、微服务仓库、单体老工程甚至 Android 工程也能借鉴大部分思路。内容会覆盖环境准备、配置缓存、构建缓存、并行参数、依赖治理、问题排查六个层面最终附上完整的实测对比数据和踩坑记录。我会尽量把每一步背后的原理讲清楚因为只抄配置不搞懂机制换一个项目大概率会翻车。1. 大型项目构建慢的真相慢在配置阶段不是任务执行1.1 构建三阶段里时间都去哪了任何一个 Gradle 构建都可以切成三段配置阶段、依赖解析阶段、任务执行阶段。配置阶段会执行所有模块的build.gradle和settings.gradle把整个项目的任务图建起来依赖解析阶段负责拉取依赖、解析版本冲突任务执行阶段才真正编译代码、跑测试、打 Jar。很多人的直觉是任务执行最耗时实际上对于大型项目配置阶段才是隐藏的吞时器。我接手的那套系统有 180 多个 Gradle 子模块配置阶段要实例化上千个 Task 对象应用几十个插件还要把每个模块的依赖坐标算一遍。光这一段不做任何编译纯空跑./gradlew help都要 2 分多钟。也就是说执行阶段还没开始时间已经烧掉一大半了。这个问题的根子在于 Gradle 任务图的构建方式。只要命令行里指定了某个任务Gradle 就需要先算出所有依赖它的任务于是整个项目里大量任务对象被提前创建。模块越多任务图越复杂配置阶段就越慢。它和语言本身关系不大纯粹是图规模的线性增长几十个模块的时候无所谓上百个模块立刻原形毕露。1.2 冷缓存与热缓存的差距是数量级而不是百分比优化前我做过一次详细测量。全量构建从命令行敲下去到出结果冷缓存情况下 23 分钟热缓存情况下也有 12 分钟左右。所谓冷缓存就是 Clean 之后连~/.gradle/caches里的构建缓存都清掉所有编译依赖 JDK 模块和第三方库全部重新来。热缓存则是本地构建缓存命中跳过大部分任务的执行。这个差异揭示了 Gradle 调优的真正思路任务执行本身很难再快多少Java 编译器就那个速度但缓存能让你这轮压根不执行任务。所以提速的核心不是让每个任务跑得更快而是让该跳过的大量任务直接跳过。后面要讲的配置缓存和构建缓存目标完全一致一个解决配置阶段重复计算一个解决执行阶段重复劳动。1.3 100倍到底怎么算的标题里的 100 倍很容易被质疑我先把口径说清楚。这里比较的是一条冷启动链路优化前开发机重启后第一次跑某个子模块的单元测试Gradle 守护进程没有被复用配置阶段完整执行构建缓存为空实际耗时为 23 分 40 秒。优化后同一台机器、同一个测试用例守护进程常驻、配置缓存命中、构建缓存命中执行时间降到约 14 秒。如果按净等待时间算这个数字已经超过 100 倍。但要说所有场景都能 100 倍那是吹牛。增量构建场景下原本 8 分钟的调试型构建优化到 5 秒大约是 96 倍。只有全量无缓存构建这种极端场景可能降到 3 到 5 倍。所以这篇文章讲的 100 倍指的是命令行输入到拿到输出的端到端体验在常规开发调试场景下的提升幅度。2. 升级前的环境准备Gradle 9.4、Java 26 与工具链强制统一2.1 版本选型为什么是 Gradle 9.4 和 Java 26Java 26 对应的是 JDK 26它带来的构建相关改进主要集中在内置的 Java 编译器对增量编译的支持、更高效的类数据共享以及 JVM 层面更激进的 GC 策略。而 Gradle 9.4 完整适配了这套工具链并且在配置缓存、构建缓存、文件系统监视这几个关键能力上已经相当成熟。版本选型最忌讳拍脑袋。我的原则是Gradle 大版本尽量往新走因为构建工具自己越新对大型项目的性能优化越激进但 JDK 要看团队实际情况如果代码里大量用了旧语法或者依赖框架对高版本 JDK 支持不全硬上 Java 26 会带来额外不确定性。如果团队已经从 Java 17 或 21 迁移过来直接上 26 是值得的因为高版本 JDK 的启动速度和内存占用都更友好。升级版本时有个细节容易被忽略gradle wrapper会锁定 Gradle 版本但 JDK 可以是独立的。Gradle 9.4 本身运行在哪个 JDK 上和你的代码用哪个 JDK 编译完全是两回事。前者决定 Gradle 内部进程的启动速度和稳定后者决定产物。建议用 Java 26 跑 Gradle 守护进程同时用 Java Toolchain 把子模块编译目标锁定在 21 或者 26避免混用。2.2 绕开 distributionUrl 下载超时国内镜像与本地离线包下载 Gradle 发行版是很多团队第一次跑构建就卡住的地方。Gradle wrapper 默认从官方服务分发gradle-9.4-bin.zip在网络不稳定的情况下经常出现Could not install Gradle distribution或者Read timed out。这不代表本地配置有问题纯粹是网络路径的问题。我现在统一在gradle/wrapper/gradle-wrapper.properties里把distributionUrl指向国内镜像格式如下distributionBaseGRADLE_USER_HOME distributionPathwrapper/dists distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-9.4-bin.zip networkTimeout10000 validateDistributionUrltrue如果公司内部有 Artifactory 或 Nexus也可以把 zip 上传到内部仓库再改地址比如distributionUrlhttps\://nexus.internal.com/repository/gradle/gradle-9.4-bin.zip。这样每台新机器执行./gradlew时都会从内网下载几百 MB 的发行版几秒钟搞定。还有一招是提前在服务器或 CI 机上下载 zip手动解压到$GRADLE_USER_HOME/wrapper/dists/对应目录。虽然有点土但对离线环境特别有效。注意每次改distributionUrl后Gradle 会重新下载对应的版本不会自动复用旧版本。2.3 Java Toolchain 与编译器守护进程别再被 JDK 不匹配折磨多模块项目最怕的是模块间 JDK 不一致。某个模块用 Java 17另一个模块用 Java 21编译的时候就会出现源发行版 17 需要目标发行版 17之类的警告甚至直接报错。Java Toolchain 是解决这个问题的标准做法它通过声明工具链要求让 Gradle 自动寻找匹配的 JDK。java { toolchain { languageVersion.set(JavaLanguageVersion.of(21)) } }设置好之后即使本机默认 JDK 是 26Gradle 也会自动去找 JDK 21 来编译这个模块找不到就下载。这个机制避免了开发者本机能跑、CI 上崩、同事电脑上又另一个样的窘境。代价是多一层工具链解析所以建议在最顶层的build.gradle.kts里统一声明一次子模块不要再重复声明否则配置阶段又白白多花时间。注意工具链解析在首次运行时会扫描本机所有 JDK 目录速度稍慢。可以在gradle.properties里设置org.gradle.java.installations.auto-detectfalse减少扫描范围但前提是你手动指定了准确路径。2.4 内存参数与 GC 策略给构建进程一个稳定的家Gradle 守护进程默认 JVM 参数对大型项目是不够的。我曾经遇到java: OutOfMemoryError: insufficient memory根因是 metaspace 设置太小构建过程中加载了大量插件类。现在我在gradle.properties里固定使用这套参数org.gradle.jvmargs-Xmx6g -XX:MaxMetaspaceSize1g -XX:UseParallelGC -XX:HeapDumpOnOutOfMemoryError -Dfile.encodingUTF-8-Xmx6g要结合机器内存看开发机 16G 内存给 6G 是可以接受的CI 容器如果只有 4G就要降到-Xmx3g。-XX:UseParallelGC这一点我要特意说明很多人习惯把服务器上的 G1GC 参数抄过来但构建任务是短平快的并行任务ParallelGC 在多核机器上的吞吐表现往往比 G1 更好。实测同一套项目ParallelGC 比 G1 的构建时间少 10% 左右。-XX:MaxMetaspaceSize1g容易被忽略。大型项目中各种框架的注解处理器、代码生成器会加载大量类默认 metaspace 只有几百 MB很容易触发频繁 Full GC。设置了 1g 之后构建进程的稳定性会明显好转。3. 真正拉开差距的核心开关配置缓存与构建缓存组合使用3.1 配置缓存让建任务图这件事只发生一次前面说过配置阶段是大项目最大的时间黑洞。Gradle 的 configuration cache 把配置阶段的结果序列化下来下次构建直接复用任务图跳过脚本执行。它和传统构建缓存是两回事一个缓存的是配置结果一个缓存的是任务产物。开启方式很简单在gradle.properties里加org.gradle.configuration-cachetrue然后跑一条冷命令比如./gradlew :core:compileJava --configuration-cache。第一次运行会输出Configuration cache entry stored.第二次再跑配置阶段直接从缓存恢复启动速度肉眼可见地快。但配置缓存不是开了就完事它的限制很多。最典型的坑是构建脚本里直接调用外部进程、读取动态属性、使用System.getProperty()等不可序列化操作。Gradle 会在启用后给出错误提示比如Build logic is not safe to store in configuration cache这时需要把相关逻辑改成惰性 API或者用providers包装。我的实际经验是先把配置缓存关闭把所有报错信息列出来逐个修复后再次开启。这个过程可能很痛苦尤其是有大量自定义插件的老项目。但收益是立竿见影的我那个 180 模块的项目配置阶段从 2 分多钟直接降到 1 秒左右。这个开关是让构建从分钟级变秒级的最关键一刀。注意配置缓存和--parallel同时开启时效果最好但如果某个任务在配置期间直接读取了另一个模块的构建结果可能会因为执行顺序变化而报错。遇到这种问题不要急着关配置缓存先定位是谁在配置阶段依赖了执行结果。3.2 构建缓存同一个输入只编译一次构建缓存解决的是执行阶段重复劳动。它把任务输入源码、依赖、注解处理器配置和输出编译产物、测试报告做哈希映射下次执行相同任务时如果输入哈希一致直接从缓存里取产物不重新编译。这听起来有点像增量编译但增量编译是本地文件级别的比较构建缓存是任务级别的复用。开启配置在gradle.propertiesorg.gradle.cachingtrue这会启用本地构建缓存。默认目录在~/.gradle/caches/build-cache-1CI 和开发者本地共用的话还可以配置远程 HTTP 缓存或者使用 Gradle Enterprise。我这次没有引入远程服务本地缓存已经够用因为开发场景主要靠它做增量跳过。这里要特别提一嘴增量编译。Gradle 自带增量 Java 编译只编译变化的源码文件但这是同一份源码改动前后的跳过而构建缓存是不同分支、不同机器上同一份源码的跳过。两者是互补关系。只开构建缓存不开配置缓存冷启动还是慢只开配置缓存不开构建缓存配置快但执行阶段还是重组合起来才是完整方案。3.3 缓存键会被哪些东西干扰Lombok、注解处理器和依赖状态构建缓存最容易在细节上翻车。一个典型问题是 Lombok。Lombok 是编译期注解处理器理论上它参与编译过程会影响输出但 Gradle 默认不会把它纳入缓存键计算。如果项目里 Lombok 版本升级了旧缓存可能被错误复用导致编译产物有兼容问题。我在升级 Lombok 时都会保守地清理一次构建缓存避免踩到脏缓存。另一个干扰项是动态版本依赖比如latest.release或者1.。这种版本每次解析可能取到不同的具体版本但 Gradle 缓存键计算时可能只在第一次解析后锁定导致实际依赖变了缓存仍然命中。正确做法是在settings.gradle.kts里开启依赖锁定或者干脆把动态版本改成固定版本。configurations.all { resolutionStrategy.cacheDynamicVersionsFor(0, seconds) resolutionStrategy.cacheChangingModulesFor(0, seconds) }这套策略虽然让依赖解析变慢但保证了缓存键的准确性。构建提速的前提是构建结果正确如果为了速度牺牲正确性那这个优化就是负优化。3.4 配置缓存和构建缓存的配合方式以及最容易踩的兼容性坑配置缓存开启后任务实现里的Project对象访问方式会被严格限制。Gradle 官方推荐所有输入都用Input、InputFile这类注解声明避免在任务执行时动态读取文件。但老项目里大量任务是用doLast写的执行时还能访问整个 Project开启配置缓存后会直接抛异常。我处理过最头疼的一个坑是自定义插件里用了project.afterEvaluate。在配置缓存模式下afterEvaluate的执行时机和普通模式不同某些本来按顺序执行的初始化代码被推迟了导致任务输入为空。最后的解法是改成配置时直接计算而不是延迟到评估阶段。这意味着代码结构要调整不是改几行配置就完事。如果你在改造期间不想让配置缓存全量阻塞开发可以用--configuration-cache-problemswarn先把错误降级为警告让构建继续跑。等团队开发节奏不紧张时再集中一个迭代把所有警告清掉。我在项目里就是这么过渡的大概花了两周时间把 70 多个配置缓存兼容性问题全部清理干净。4. 让 CPU 和内存全部运转起来并行化与后台守护进程调参实战4.1 并行构建别让 CPU 闲坐着等某个模块大型项目优化完配置阶段和缓存下一步是榨干机器资源。Gradle 默认是串行构建多个子模块的任务执行是排队完成的。开启并行构建只需要一行org.gradle.paralleltrue这个参数允许 Gradle 同时执行相互独立的模块任务对多核机器收益极大。我的项目在 16 核机器上全量构建从 12 分钟降到 7 分钟前提是内存足够并行跑多组编译任务。并行度默认是 CPU 核心数减一如果想要更激进可以设置org.gradle.workers.max16这个workers.max控制的是任务内部的最大 worker 数。比如 Java 编译任务内部会启动多个编译进程这个值决定了同时有多少个编译线程在跑。调太高有风险因为每个编译进程都会占内存建议按机器内存 / 3G来估算上限16G 内存设置 4 到 6 比较稳妥32G 内存再考虑拉高到 10 以上。4.2 守护进程构建缓存之外最容易被忽视的加速器Gradle 守护进程daemon是长时间驻留的后台进程负责复用 JVM、类加载结果和编译缓存。如果守护进程每次构建都重启等于每次都要重新做 JVM 启动和类加载这部分大概要消耗 5 到 10 秒对分钟级构建可能无所谓但对秒级构建就是致命伤。为了保证守护进程常驻可以在gradle.properties里设置org.gradle.daemontrue同时还要注意耐心不要让守护进程因为空闲超时被回收。Gradle 默认空闲 3 小时后停止守护进程可以用org.gradle.daemon.idletimeout14400000延长到 4 小时。我在开发机上设了 24 小时配合系统的开机启动基本做到全天候守护进程不退出。注意一次性调试多个 Gradle 版本时每个版本会有独立的守护进程。如果机器上同时跑 Gradle 9.4 和 Gradle 8.x内存占用会翻倍。建议用./gradlew --stop定期清理不常用的守护进程。4.3 文件系统监视让增量构建的输入感知从秒级降到毫秒级Gradle 9.4 默认启用了文件系统监视VFS watch。它通过监听文件变化事件维护一个虚拟文件系统构建时不需要重新扫描整个源码目录直接对比事件日志就知道哪些文件变了。这在大型项目里效果非常明显因为扫描成千上万个文件的时间往往比编译本身还长。相关配置org.gradle.vfs.watchtrue如果你在 IDE 外频繁用命令行操作文件或者项目目录挂载在网络盘上文件系统监视可能失效。这种情况会出现VFS will be recreated的提示然后变回全量扫描模式。解决办法是确保源码目录在本机磁盘上CI 环境如果用的是容器挂载卷需要先看文件系统类型是否支持 inotify。开了文件系统监视之后原本一次改动触发的增量构建文件扫描时间从 4 秒左右降到 0.2 秒。这个数据和编译器优化无关纯粹是省去了冗余扫描。构建速度的体验感很多时候是被这种小地方拉起来的。4.4 我的调参历程从 8 分钟到 5 秒的每一步我调优不是一次到位的每改一个参数都会用 profile 报告对比避免凭感觉。最初的基准是在 16 核 32G 机器上单测命令耗时 8 分 12 秒。第一步只开并行耗时降到 6 分 40 秒。第二步开配置缓存降到 1 分 20 秒。第三步清理缓存兼容性警告并开启构建缓存降到 18 秒。第四步调整 JVM 参数把 metaspace 从 512M 提到 1G降到 15 秒。第五步开文件系统监视降到 12 秒。最后把 Gradle 从 8.x 升级到 9.4Java 从 21 升到 26降到 5 秒左右。整个过程中每一步的收益来源都不一样。并行吃的是多核红利配置缓存吃的是跳过配置阶段构建缓存吃的是跳过任务执行JDK 升级吃的是 JVM 本身的效率。如果直接全量开启再测试虽然最终数字很好看但你不知道瓶颈到底在哪出了问题也没法定位。5. 大型多模块项目的依赖与任务编排减少配置阶段的工作量5.1 依赖约束集中管理版本冲突解析别每次全量跑多模块项目最常见的乱象是每个模块各写各的依赖版本。比如guava在 A 模块写 31.0在 B 模块写 32.0Gradle 在运行时会做一次全量版本解析选择最高版本并输出冲突警告。模块多了以后这个解析过程会拖慢依赖解析阶段。推荐做法是在根项目的build.gradle.kts里统一管理依赖约束子模块只声明用哪个依赖不写版本号。类似 Maven 的 BOM 理念dependencies { constraints { implementation(com.google.guava:guava:33.0.0-jre) implementation(org.xerial:sqlite-jdbc:3.45.0.0) } }这样版本冲突的解析范围被大幅缩小依赖解析阶段从 20 多秒降到 5 秒以内。同时要尽量避免使用 SNAPSHOT 或动态版本它们会强制 Gradle 频繁访问远端仓库检查更新这种情况下无论本地缓存怎么配置都会产生额外的网络延迟。5.2 按需配置不要为了跑一个模块把整个项目都配置一遍Gradle 有一个configure-on-demand优化只在必要时配置当前任务依赖的模块。它的效果是把配置全部模块变成配置最少模块。很多人会直接开org.gradle.configureondemandtrue但我要提醒这个参数对某些项目会引入副作用。因为它只在配置阶段执行必要的模块脚本如果某个模块的配置脚本依赖了其他模块的状态可能拿到错误的值。使用前建议跑一轮完整全量测试确认没有副作用。对于我那个 180 模块的项目这个开关单独用收益不大因为业务模块之间依赖链条很深最终仍然要配置大部分模块。真正见效的是配合将大模块拆解为按能力聚合的任务分组平时调试只跑:core:test不触发:web:bootJar这类重量级任务。5.3 惰性任务注册让不需要的任务不创建很多自定义任务只是备而不用。Gradle 支持register惰性创建任务对象而不是在配置阶段就用create把所有任务实例化tasks.register(integrationTest) { description 运行集成测试 useJUnitPlatform() }register版本只有在任务真正执行时才会实例化对象、计算输入输出。如果一个项目里有几百个自定义任务但平时基本不跑register能明显减少配置阶段的开销。这是我用 Gradle 9.4 之后特别推荐的一种写法它把任务创建的成本从构建启动时转移到了任务执行时。类似的思路还有configuration.remoteCache、configurations.create这些 API 的惰性化。大项目改这些可能要动很多代码但增量收益是可观的。如果团队正在新建项目建议一开始就使用惰性 API避免后面重构。5.4 API 依赖与 implementation编译类路径瘦身Java 插件的api和implementation配置直接影响编译类路径的大小。如果大量使用api子模块编译时会看到完整的传递依赖类类路径无限膨胀配置阶段和编译阶段的耗时都会上升。改成implementation后Gradle 会隐藏内部依赖只在当前模块编译时暴露。这个改动对速度的影响没有前面几个参数明显但对编译内存和缓存命中率有正反馈。类路径越小增量编译时比较的文件越少缓存键越稳定。我把项目里 80% 的api依赖改成implementation之后编译类路径平均缩小了 40%编译器内存占用下降了约 30%。5.5 使用 includeBuild 构建复合项目避免所有模块打成一个大构建如果仓库里存在平台组件 业务应用的架构可以考虑用复合构建composite build把各自独立的 Gradle 构建组合起来而不是把它们拆成同一个构建的无数个模块。复合构建允许两个构建并行构建、互相引用产物但对配置阶段的整体复杂度和依赖解析时间更可控。当然这不是所有场景都适合。复合构建在 IDE 支持上偶尔有怪问题比如跨构建的代码跳转有时候会失灵。如果是纯 Java 服务端项目且模块之间本来就是强依赖关系复合构建带来的复杂度可能大于收益。我的看法是只有组件库单独发布、单独构建、且多个应用共同依赖它的时候才值得用includeBuild。6. 量化验证与典型报错排查从 20 分钟到 2 分钟的实测记录6.1 用 --profile 和 --scan 找出每一段耗时调优必须做量化没有数据支撑的优化都是安慰剂。Gradle 自带的--profile会生成一份 HTML 报告按阶段展示耗时./gradlew :core:test --profile --configuration-cache报告会在build/reports/profile/目录下生成列出配置阶段、依赖解析、任务执行三个阶段的明细。看报告的时候重点看两项配置阶段的总时间以及每个任务的耗时分布。如果配置阶段时间还是高说明配置缓存没生效如果某个任务耗时长但输出没变化要检查它是不是没有正确声明输入输出导致缓存无法命中。--scan是更完整的构建扫描能输出到 Gradle 的云服务或者自建服务。但它会把任务输入哈希、缓存命中率这些细节都暴露出来如果你的代码涉及敏感信息注意不要外传。我的项目因为安全要求不允许用外部服务所以--scan只在本地跑过一次做诊断后续以--profile为主。6.2 一次真实的基线对比数据以下是我在同样一台开发机上记录的对比数据内存 32GCPU 16 核项目 180 个模块Gradle 9.4JDK 26场景优化前优化后倍数单测命令热守护进程、缓存已预热8 分 12 秒5.2 秒约 96 倍全量 assemble本地缓存命中23 分 40 秒14.3 秒约 100 倍Clean 后全量 assemble无本地缓存23 分 20 秒7 分 35 秒约 3 倍配置阶段耗时2 分 10 秒0.9 秒约 145 倍注意第一行和第二行的优化后都基于缓存和配置缓存已就绪。如果你把~/.gradle/caches清空任何优化都救不了你因为编译器本身的性能提升有限。所以这个对比反映的是开发场景下的真实体验不是基准性能的绝对提升。6.3 高频报错与处理清单别再卡在这些常见坑上调优过程中我踩过不少报错很多是换版本后才会出现的这里整理成清单方便直接查。第一个是OutOfMemoryError: insufficient memory。开并行之后内存很容易打满尤其是多个编译 worker 同时启动时。解决办法是先调低org.gradle.workers.max再检查org.gradle.jvmargs里的-Xmx是否和机器内存匹配。32G 机器建议-Xmx6g起步别贪心开 8g不然跑来跑去内存不足反而崩。第二个是 Lombok 相关的you arent using a compiler supported by lombok, so lombok will not work。这是 JDK 升级后常见的问题Lombok 版本太老不支持 Java 26 的编译接口。解决方法是升级 Lombok 到支持 JDK 26 的版本比如 1.18.34 及以上。如果升级后还有警告检查是否有自定义注解处理器在 Lombok 之前执行。第三个是Could not install Gradle distribution from ...本质上还是distributionUrl下载超时。除了换镜像网络环境较差时可以把networkTimeout调大或改成https://downloads.gradle.org/distributions/gradle-9.4-bin.zip这个官方直链。某些内网环境只允许特定域名则需要走公司代理。第四个是Gradles dependency cache may be corrupt。这个报错经常伴随着网络异常比如下载依赖时中断导致缓存文件损坏。稳妥的办法是关掉 Gradle 守护进程后清理缓存目录./gradlew --stop rm -rf ~/.gradle/caches/modules-2清理后重新拉取依赖会多花几分钟但能彻底解决脏缓存问题。不建议只删单个依赖目录因为 Gradle 的缓存索引文件可能已经不一致。6.4 我实际检查过一轮之后发现的伪优化最后想提醒一点不是所有能提升温度的参数都值得上。我测试过org.gradle.cachingtrue和远程 HTTP 缓存一起使用但在团队没有统一 CI 节点的情况下远程缓存每次上传下载的开销比本地缓存节省的时间还多最后只能关闭。类似地org.gradle.forkCount调太高会导致 CPU 上下文切换频繁反而变慢。所以每个参数都要在小范围试点验证再推广到全项目。一家公司的网络环境、机器配置、团队开发习惯完全不同适合我的参数不一定适合你。重要的是掌握排查方法和性能分析手段而不是抄一份万能配置。最后再分享一个团队落地的小技巧把这份gradle.properties的调整记录维护在项目的docs/build-performance.md里每次改动都写清楚改了什么、为什么改、实测收益多少。后来新同事加入看到这份文档就能快速理解构建配置的来龙去脉而不是把gradle.properties当成一堆永远不要动的魔法数字。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门