Sam Pengilly
06/11/2025, 6:33 AM-Xmx4g
setting on the gradle daemon tends to only use about 5gb max between the main daemon process and all child processes. Looking at a build scan it appears to rarely reach that amount and spends most of the build using around 2-4gb of memory. Running htop on the macbook while the build runs shows that the total used memory on the machine (including all other apps, browser, slack, etc) hovers stably around 5-7gb.
Meanwhile if I run exactly the same build, with exactly the same gradle properties (specifying the same number of max workers) inside a docker image on the same macbook (docker configured with 10gb max memory), all of a sudden that build continues to eat more and more memory, eventually blowing past 8-9gb and eventually using all 10gb available resulting the daemon being killed in the background.
I'm not sure what to make of it. It implies there's something going on either in the OS (ubuntu vs macOS) or in docker, or the JVM, or in gradle itself. I've tried dozens of different combinations of JVM options and flags, I'm running Java 21 for the build toolchain on top of a Java 23 installation so flags like UseContainerSupport
should be on by default. I've toyed with ensuring that MaxMetaspace
is set when overriding org.gradle.jvmargs
, I've set Java options globally for all java instances to try to constrain memory of child processes, etc. None of it has seemed to have any effect.Sam Pengilly
06/11/2025, 7:39 AMeclipse-temurin
(23 specifically).
I just tried another image with a different linux base (amazon corretto 24-jdk
on amazon linux), it appeared a bit more stable. It filled the memory up to 9.5gb (9.7gb available) but it appeared to perform more garbage collections to keep it there. It got significantly further in the build. The main gradle daemon was using over 8gb of memory though, twice the configured 4gb.
Eventually something pushed it over the edge though and it was also killed due to memory exhaustionysb33r
06/11/2025, 4:34 PMforkEvery
to a low value when running in CI.Sam Pengilly
06/11/2025, 10:36 PMSam Pengilly
06/11/2025, 11:53 PMSam Pengilly
06/12/2025, 1:34 AMSam Pengilly
06/12/2025, 1:35 AMJulien Plissonneau Duquène
06/12/2025, 2:45 PMjconsole
to check what the actual memory usage and limits are from the JVM point of view. This will also tell you how close to the limit your build gets.
Note that you have 3 different JVMs running, each of them with a different place to set memory limits:
• the JAVA_OPTS
environment variable for the launcher, but you should not need to set any limit there
• the org.gradle.jvmargs
property for the Gradle daemon
• the kotlin.daemon.jvmargs
property for the Kotlin daemon.
I would recommend settings limits with -Xmx
and similar rather than RAM %. The Kotlin daemon inherits some arguments from the Gradle daemon, but won't take into account the RAM already used by Gradle. If other JVM processes are launched by the build (e.g. to run tests) they may have their own arguments defined elsewhere in build scripts.
Finally you have to leave some room (up to 50% in constrained environments such as yours) for OS/filesystem/other processes overhead, which will also be accounted as RAM usage by the container.Sam Pengilly
06/12/2025, 10:31 PMJAVA_TOOL_OPTIONS
memory limits. All of the above appear to be straight up ignored in the case of the gradle daemon.
There's definitely more to JVM memory footprint than just the heap, but with the heap constrained to 2gb and metaspace constrained to 1gb, I certainly wouldn't expect it to be using a total of 6gb of memory, insinuating that if the heap and metaspace are properly constrained then there's 3gb of other stuff being allocatedSam Pengilly
06/12/2025, 10:35 PMJulien Plissonneau Duquène
06/13/2025, 2:30 PMrosetta
and that probably adds some significant overhead as well. Your try with 3g+1g means both JVMs could allocate up to 8 GiB together, so one of them ending up OOM-killed in such a situation is not really surprising either. Did you try jconsole
to check what it looks like from within the JVM, and see if you could further restrict memory allocation?Sam Pengilly
06/16/2025, 12:14 AMSam Pengilly
06/16/2025, 12:23 AMSam Pengilly
06/16/2025, 12:25 AM