如何针对构建持续时间和 RAM 使用优化 gradle 构建性能?
Posted
技术标签:
【中文标题】如何针对构建持续时间和 RAM 使用优化 gradle 构建性能?【英文标题】:How to optimize gradle build performance regarding build duration and RAM usage? 【发布时间】:2012-04-06 04:48:17 【问题描述】:我目前正在为我的多模块 Web 应用程序从 ant 切换到 gradle,目前看来,当前版本的 Gradle (M9) 可能会超出其限制。但也许(希望)这只是我对 Gradle 的概念不够了解或不知道“神奇的性能提升开关”的问题。我很乐意提供有关如何优化构建性能的任何提示。
问题:在显示第一个 compileJava
之前几分钟过去了,即使源中没有任何变化,该进程也会运行至少 7 分钟,直到它在 :testClasses
中途崩溃(在不同的子项目中)以下消息:
* What went wrong:
Could not resolve all dependencies for configuration ':mysubproject_X:testRuntime'.
> Java heap space
该项目由大约 30 个(部分相互依赖的)子项目组成,它们的 build.gradle 或多或少相同,用于从每个子项目构建一个 jar 文件,例如
sourceSets
main
java
srcDirs 'src'
dependencies
compile project(':mysubproject_A')
compile project(':mysubproject_B')
compile project(':mysubproject_E')
compile group: 'commons-lang', name: 'commons-lang', version: '2.2'
// copy all non-java files from src
copy
from sourceSets.main.java.srcDirs
into "$buildDir/classes/main"
exclude '**/*.java'
jar
我试图通过将最大内存大小提高到 1024M 来解决堆空间问题,但它没有帮助。我的主要 build.gradle 文件如下所示:
sourceCompatibility = 1.6
version = 0.5
useFindBugs = false
apply plugin: 'java'
configurations
repositories
mavenCentral()
mavenRepo url:"http://repository.jboss.org/maven2", artifactUrls: ["https://repository.jboss.org/nexus/content/repositories/public","http://opensource.55minutes.com/maven-releases"]
dependencies
buildscript
repositories
mavenRepo url: 'http://gradle.artifactoryonline.com/gradle/plugins'
flatDir(dirs: "$projectDir/lib")
dependencies
classpath "org.gradle.plugins:gradle-idea-plugin:0.3.1"
subprojects
apply plugin: 'java'
apply plugin: 'idea'
repositories
mavenCentral()
mavenRepo url:"http://repository.jboss.org/maven2", artifactUrls: ["https://repository.jboss.org/nexus/content/repositories/public","http://opensource.55minutes.com/maven-releases"]
dependencies
testCompile 'junit:junit:4.8.2'
compileJava
options.encoding = 'UTF-8'
options.fork (memoryMaximumSize: '1024m')
javadoc
options.encoding = 'UTF-8'
test
testReportDir = file(rootProject.testReportDir)
forkEvery = 1
jvmArgs = ['-ea', '-Xmx1024m']
dependsOnChildren()
task wrapper(type: Wrapper)
gradleVersion = '1.0-milestone-9'
【问题讨论】:
你碰巧要替换令牌吗?我发现这是导致多项目 Gradle 构建速度慢一个数量级的原因,因为我们在 .gradle 缓存上进行令牌替换。 感谢您的建议。但是,没有涉及替换。 Peter Niederwieser 在下面的回答成功了:) 【参考方案1】:你需要给 Gradle JVM 更多内存,而不是给编译任务/JVM。一种方法是通过 GRADLE_OPTS
环境变量 (GRADLE_OPTS=-Xmx512m
)。
【讨论】:
谢谢,按照建议将 GRADLE_OPTS 设置为 -Xmx512m 不仅消除了堆空间错误,而且大大加快了进程。构建仍然需要相当长的时间,在某些时候我不确定 Gradle 在后台做什么,但我可以从这里继续使用分析器 :) 当设置为 512 时,我再次得到同样的错误;但是当我将它设置为例如 2048 时,我得到“无法为 2097152 保留足够的空间”【参考方案2】:如果使用Gradle Wrapper,您可以像这样在gradlew
中设置DEFAULT_JVM_OPTS
:
DEFAULT_JVM_OPTS="-Xmx512m"
如果您使用的是 Windows,请在 gradlew.bat
中以类似的方式设置它:
set DEFAULT_JVM_OPTS=-Xmx512m
Gradle Wrapper 任务也可以修改为自动包含此内容。 Gradle developers 就是这样解决的:
wrapper
gradleVersion = '1.8'
def jvmOpts = "-Xmx512m"
inputs.property("jvmOpts", jvmOpts)
doLast
def optsEnvVar = "DEFAULT_JVM_OPTS"
scriptFile.write scriptFile.text.replace("$optsEnvVar=\"\"", "$optsEnvVar=\"$jvmOpts\"")
batchScript.write batchScript.text.replace("set $optsEnvVar=", "set $optsEnvVar=$jvmOpts")
【讨论】:
从 Gradle 2.9 开始修改包装器任务也有效 我建议你在给代码sn-ps的时候也应该说明文件的关注点和它们的文件路径。 据我所知,这可以放在任何 Gradle 构建文件中。【参考方案3】:我正在使用以下版本的 gradle.properties 来使 android 项目中的 Gradle 性能更好
# The Gradle daemon aims to improve the startup and execution time of Gradle.
# When set to true the Gradle daemon is to run the build.
org.gradle.daemon=true
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
org.gradle.parallel=true
# Enables new incubating mode that makes Gradle selective when configuring projects.
# Only relevant projects are configured which results in faster builds for large multi-projects.
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:configuration_on_demand
org.gradle.configureondemand=true
【讨论】:
这很好用,虽然我必须在我的项目中禁用并行,我认为这是因为自定义 gradle 插件正在改变现有的 JAR,而不是产生新的输出并留下原始文件。如果并行没有像其他人预期的那样工作,请深思。【参考方案4】:我刚刚找到了一个很好的方法来处理这个问题。不需要自定义 gradle 包装器或 GRADLE_OPTIONS。
compileJava
options.fork = true // Fork your compilation into a child process
options.forkOptions.setMemoryMaximumSize("4g") // Set maximum memory to 4g
使用 --info 选项运行 Gradle,以查看它将在哪里使用您的参数以获得最大内存大小。
gradle build --info
【讨论】:
在您的build.grade
中。从那时起,语法发生了一些变化。这是JavaCompile docs。【参考方案5】:
在 gradle.properties 文件中添加以下行:
org.gradle.daemon=true
这将促进构建 - 取自
https://www.timroes.de/2013/09/12/speed-up-gradle/
【讨论】:
java heap 好像有点超载了,过了一会儿就去掉了,现在考虑SSD盘作为下一个性能阶段 gradle daemon 默认开启【参考方案6】:将以下内容作为 gradle.properties 放入 ~/.gradle
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Settings specified in this file will override any Gradle settings
# configured through the IDE.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# The Gradle daemon aims to improve the startup and execution time of Gradle.
# When set to true the Gradle daemon is to run the build.
# TODO: disable daemon on CI, since builds should be clean and reliable on servers
org.gradle.daemon=true
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
org.gradle.jvmargs=-Xmx6g -Xms4g -XX:MaxPermSize=8g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
org.gradle.parallel=true
# Enables new incubating mode that makes Gradle selective when configuring projects.
# Only relevant projects are configured which results in faster builds for large multi-projects.
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:configuration_on_demand
org.gradle.configureondemand=true
【讨论】:
开启 gradle 守护进程通常可以很好地加速 gradle。每次调用 gradle 时,它都必须加载并解析构建文件,然后才能开始执行。守护进程将加载/解析和缓存解析的数据。下一次调用,如果构建文件没有改变,它会更快。但是,如果您曾经执行过“gradle --debug我亲自浏览了这里的所有文章,但执行这些步骤可以解决问题。
如果您使用的是 32 位 jvm,则安装 64 位 jvm。
-
转到控制面板(在 windows 10 中搜索 java)
找到java应用程序
双击java,然后查看。
在运行时参数添加:
-Xmx 2048m
【讨论】:
对于任何寻找“运行时参数”的人,在 W7 中,一旦您执行第 3 步,它就位于“Java”选项卡下,然后单击“查看”。从那里,“运行时参数”将被视为网格中的单元之一。 谢谢!我安装了 32 位和 64 位 Java,gradle 使用 32 位而不是 64 位。【参考方案8】:以上答案都不适合我,然后我发现了这个-
我的系统配置-
Windows x64 - JDK 32 bit - Cordova 5.4.1 - Ionic 1.7.12
可以通过环境变量设置运行 Gradle 的 JVM 选项。您可以使用 GRADLE_OPTS 或 JAVA_OPTS,或同时使用两者。 JAVA_OPTS 按照惯例是许多 Java 应用程序共享的环境变量。一个典型的用例是在 JAVA_OPTS 中设置 HTTP 代理,在 GRADLE_OPTS 中设置内存选项。这些变量也可以在 gradle 或 gradlew 脚本的开头设置。
我添加了下面提到的两个环境变量并解决了这个问题-
Variable Name: GRADLE_OPTS
Variable Value: -Xmx512m
Variable Name: JAVA_OPTS
Variable Value: -Xmx512m
希望这对像我这样的人有所帮助。
【讨论】:
【参考方案9】:gradlew 中的 GRADLE_OPTS 值之前是这样为我设置的
DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
这导致 compileJava 在 Jenkins 中失败,如下所示
出了什么问题: 任务 ':compileJava' 执行失败。 超出 GC 开销限制
后来我更改了如下所示的 DEFAULT_JVM_OPTS 以使 Jekin 构建成功 -
DEFAULT_JVM_OPTS="-Xmx512m" "-Xms64m"
【讨论】:
以上是关于如何针对构建持续时间和 RAM 使用优化 gradle 构建性能?的主要内容,如果未能解决你的问题,请参考以下文章
Xcode 服务器集成缓存位置、Ram 磁盘和 _xcsbuildd
(android)如何发现和解决(NullPointerException)空指针异常问题(持续优化)
在使用 Maven 的 Eclipse 中,我想将我的构建目录放在 ram 驱动器中。如何指定 project.build.directory?