为 Jenkins/gradle 增加 PermGen space

Increasing PermGen space for Jenkins/gradle

我是 运行 Mac Mini (10.9.5) 上的 Android 项目的 Jenkins 构建。 Jenkins 构建失败并显示如下错误消息:

<package>.myTest > test_myTest FAILED
org.mockito.cglib.core.CodeGenerationException at test_myTest.java:65
Caused by: java.lang.reflect.InvocationTargetException at test_myTest.java:65
Caused by: java.lang.OutOfMemoryError at test_myTest.java:65
java.lang.OutOfMemoryError: PermGen space

这之后有时会出现类似

的消息
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "/0:0:0:0:0:0:0:1:50340 to /0:0:0:0:0:0:0:1:50339 workers Thread 2"
16:47:17 
16:47:17 Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "/0:0:0:0:0:0:0:1:50340 to /0:0:0:0:0:0:0:1:50339 workers Thread 4"
16:47:18 
16:47:18 Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "/0:0:0:0:0:0:0:1:50340 to /0:0:0:0:0:0:0:1:50339 workers Thread 5"
16:47:18 
16:47:18 Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "/0:0:0:0:0:0:0:1:50340 to /0:0:0:0:0:0:0:1:50339 workers Thread 6"
16:47:19 

它通常在构建的同一点失败。根据 Jenkins wiki

Do you consistently see OOME around the same phase in a build? If so, maybe it just needs a bigger memory.

这可能意味着我只需要更多 PermGen space。

我读过的 Whosebug posts/blog 帖子表明我需要增加最大 PermGen 大小(例如 -XX:MaxPermSize=1024M)。但是,我不清楚在哪里执行此操作。

我已经为 GRADLE_OPTSJAVA_OPTS 更改了此设置,因此我的 Jenkins 构建环境如下所示:

如屏幕截图所示,我还按照建议为垃圾收集 Perm Gen 添加了一些选项 here

这似乎有效——我昨天成功构建了一些,但现在又失败了(据我所知没有任何变化)。

阅读 this answer 后,我还在项目的 gradle.properties 文件中更改了以下行。

org.gradle.jvmargs=-Xms1024M -Xmx2048M -XX:PermSize=512M -XX:MaxPermSize=2048 -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

这并没有解决问题。

this and this 等类似问题的回答让我觉得我可能以错误的方式处理这个问题——我是否应该更改 Mac (10.9.5) 的计算机设置,即 运行詹金斯?修改PermGen的正确方法是什么space?

编辑:我之前以为可能没有设置环境变量,但我证实它们出现在构建结果环境变量下 (jenkins/job/<Project>/146/injectedEnvVars/)

内存设置是根据 运行 JVM 进程设置的。所以你绝对不需要设置任何 OS 变量或系统范围的设置来解决这个问题。

您首先需要确定哪个进程引发了错误。 我假设它是 Gradle 构建而不是 Jenkins 本身。 是Gradle构建,你还不知道是哪个进程。

默认情况下,Gradle 测试任务在单独的 jvm 中执行测试,因此在这种情况下更改 gradle.properties 中的值对您没有帮助。 在这种情况下,您需要正确配置 Gradle 测试任务,例如:

test {
    jvmArgs "-XX:MaxPermSize=2048m"
}

正如 Integrating Stuff 所说,有必要增加单元测试的 MaxPermSize。我在 "Running from Gradle" 部分找到了如何这样做 here

android {
    testOptions {
        unitTests.all {
            jvmArgs '-XX:MaxPermSize=1024m' //prevent OOM (PermGen space) while running tests
        }
    }
    ...
}