docker - 如何解决 gradle 在 docker 环境中被破坏的问题?

标签 docker jenkins gradle

Gradle在docker环境下无法正常工作,注定会占用过多的内存而被kill掉。

内存管理器使用下面的类获取它的快照

https://github.com/gradle/gradle/blob/master/subprojects/process-services/src/main/java/org/gradle/process/internal/health/memory/MemInfoOsMemoryInfo.java

特别是 Gradle 通过读取/proc/meminfo 来确定剩余多少可用内存,这在容器中提供了不准确的读数。

Gradle 仅在收到请求以创建具有更大最小堆大小的新工作程序守护程序时才终止工作程序守护程序,然后根据此阅读可用。

因此,Gradle 将继续制造 worker ,直到它用完容器的分配数量并被杀死。

有人对此有解决方法吗?真的不明白为什么这对更多人来说不是问题。我想只有当你的工作守护进程不能被重用而创建新的守护进程时,这才会真正成为一个问题,这对我来说就是这种情况,因为我有大量的模块。

我有一个临时解决方法,其中我给每个生成的 jvm 一个巨大的 -Xms,所以它总是触发最小堆大小 > 可用,所以总是删除之前的工作守护进程,但这并不令人满意。

-- 编辑

为了抢占某些东西,--max-workers 不会影响允许存在的 Worker Daemon 的数量,它只会影响允许处于事件状态的数量。即使使用 --max-workers = 1,也允许有任意多个空闲的 Worker Daemon。

最佳答案

编辑 - 忽略下面的内容,它有些工作,但我已经通过覆盖 MemInfoOsMemoryInfo 类来修补 Gradle,它工作得更好。将很快提供指向 MR 到 Gradle 的链接。

找到一个合理的解决方法,我们监听操作系统内存更新,每次完成任务时,我们请求比确定可用内存更多的内存,确保守护进程停止。

import org.gradle.process.internal.health.memory.OsMemoryStatus
import org.gradle.process.internal.health.memory.OsMemoryStatusListener
import org.gradle.process.internal.health.memory.MemoryManagertask 

task expireWorkers {
    doFirst {
        long freeMemory = 0

        def memoryManager = services.get(MemoryManager.class)
        gradle.addListener(new TaskExecutionListener() {
            void beforeExecute(Task task) {
            }
            void afterExecute(Task task, TaskState state) {
                println "Freeing up memory"
                memoryManager.requestFreeMemory(freeMemory * 2)
            }
        })
        memoryManager.addListener(new OsMemoryStatusListener() {
            void onOsMemoryStatus(OsMemoryStatus osMemoryStatus) {
                freeMemory = osMemoryStatus.freePhysicalMemory
            }
        })
    }
}

关于docker - 如何解决 gradle 在 docker 环境中被破坏的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64959614/

相关文章:

jenkinsfile 没有将 env 传递给 sh

android - NestMember 需要 ASM7

java - 由于 API 问题导致应用程序崩溃

jenkins - 在 Jenkins 上的 Kubernetes 插件中为 pod 模板设置污点

docker-compose up 问题使用 Docker Apple M1

docker - 带有自托管 Ubuntu 机器 : docker fails 的 Azure DevOps

windows - 在与主(和主机)不同的操作系统上运行 Jenkins 从属

Jenkins 主从交互

Java 和 Gradle : split in multiple projects or use different SourceSets?

ubuntu - Nginx client_max_body_size 在 AWS Elastic Beanstalk 上的 Docker 容器中不起作用