如何针对构建持续时间和 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 ”,它会失败,因为您试图查看类路径、变量的值等等。您必须关闭配置中的守护进程,kill -9进程 THEN 执行 --debug THEN,完成调试后,在配置中将其重新打开。【参考方案7】:

我亲自浏览了这里的所有文章,但执行这些步骤可以解决问题。

如果您使用的是 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

如何仅针对工作执行应用程序优化 build.xml 文件

优化构建时间

(android)如何发现和解决(NullPointerException)空指针异常问题(持续优化)

在使用 Maven 的 Eclipse 中,我想将我的构建目录放在 ram 驱动器中。如何指定 project.build.directory?

使用Python分析ELF文件优化Flash和Sram空间的案例