Philipp Nowak
08/21/2025, 9:29 AM./gradlew :app:dependencies
I receive the following exception:
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "pool-1-thread-1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
I am using org.gradle.jvmargs=-Xmx10240m
and also increasing it to 12 GB didn't help. All the other tasks just run fine, e.g. building, testing etc. - the activated configuration cache is on develop for a few days now already.
Does anyone have an idea what could cause the OOM on the dependencies task and how to fix it? Deactivating the configuration cache fixes it but should not be an option here 😄TheGoesen
08/21/2025, 9:47 AMJulien Plissonneau Duquène
08/21/2025, 10:20 AMjconsole
utility to check if your heap settings make their way to the correct JVM process and the difference in heap usage between the other tasks and dependencies
. If the latter one eats several GiBs more there is definitely an issue to investigate.Vampire
08/21/2025, 10:48 AM--stacktrace
to see where the OOM happens (cli, daemon, worker, ...).
And if it is not the CLI process, the gradle-profiler
might also help to investigate what is happening with the heap.Philipp Nowak
08/21/2025, 12:19 PMVM Summary
Tab in jconsole
I can see my jvmargs values as expected. Unfortunately, HeapDumpOnOutOfMemorryError seems to have no effect. Same applies for --stacktrace
option.
Memory Usage in jconsole
is around 4 GB für Heap, so low enough I think and testDebugUnitTest
consumes even more than dependencies
but doesn't throw OOM, that's strange.
I will have a look on the gradle-profiler
TheGoesen
08/21/2025, 12:23 PMVampire
08/21/2025, 12:23 PMHeapDumpOnOutOfMemorryError seems to have no effectProbably because wrong process, that's why I said, check first where the error happens
Same applies forOf course it still fails, but it shows you the full stacktrace where you can see where it happens, as I said.option--stacktrace
Philipp Nowak
08/21/2025, 12:24 PM--stacktrace
does not give any additional outputVampire
08/21/2025, 12:24 PMusing the JAVA_OPTSIf so, better
GRADLE_OPTS
or you hit all start scripts that look at JAVA_OPTS
Vampire
08/21/2025, 12:24 PMI meantThen what is the full stacktrace?does not give any additional output--stacktrace
Vampire
08/21/2025, 12:25 PMVampire
08/21/2025, 12:25 PMPhilipp Nowak
08/21/2025, 12:29 PMTheGoesen
08/21/2025, 12:34 PMPhilipp Nowak
08/21/2025, 12:35 PMVampire
08/21/2025, 12:39 PMgradle-profiler
will help if it indeed is a CLI process problem.
Does it fix it if you use GRADLE_OPTS
to increase the CLI process max heap, respectively do you get a heap dump if you there add the dump option?Vampire
08/21/2025, 12:39 PMGRADLE_OPTS="...." ./gradlew ...
in case you didn't knowPhilipp Nowak
08/21/2025, 12:49 PMGRADLE_OPTS="-Xmx10240m -XX:+HeapDumpOnOutOfMemoryError" ./gradlew :app:dependencies --stacktrace
the task is running successfully 🤔Vampire
08/21/2025, 12:50 PMVampire
08/21/2025, 12:50 PMPhilipp Nowak
08/21/2025, 12:51 PMjava.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid10549.hprof ...
yupVampire
08/21/2025, 12:51 PMJulien Plissonneau Duquène
08/21/2025, 12:52 PMjconsole
on a process that fails take a look at the Memory tab and check the various charts for different memory pools including non-heap to find the one that gets close to the limitVampire
08/21/2025, 12:52 PMPhilipp Nowak
08/21/2025, 12:53 PMVampire
08/21/2025, 12:54 PM64m
).Julien Plissonneau Duquène
08/21/2025, 12:54 PMI'd say non-heap is not the problemit didn't help above, and OP wrote usage stayed around 4GB so it's worth looking IMO, won't take long...
Julien Plissonneau Duquène
08/21/2025, 12:55 PMVampire
08/21/2025, 12:55 PMJulien Plissonneau Duquène
08/21/2025, 12:57 PMI've never seen the CLI process going OOM actually 😄same here, but weird things happen, and hopefully it will be easier to debug
Vampire
08/21/2025, 12:58 PMVampire
08/21/2025, 12:58 PMJulien Plissonneau Duquène
08/21/2025, 1:00 PMVampire
08/21/2025, 1:00 PMprintln(".".repeat(64 * 1024 * 1024))
works without problemPhilipp Nowak
08/21/2025, 1:00 PMOr maybe you send one line that is longer than 64m and the CLI tries to read it, no idea 😄Wait a second... This project has pretty heavy output stuff during configuration phase which I currently can't get rid of. Since the problem occurred after enabling configuration cache - might that output be the cause for it?
Julien Plissonneau Duquène
08/21/2025, 1:02 PMvisualvm
Philipp Nowak
08/21/2025, 1:03 PMgradle-wrapper.jar :app:dependencies
Process in jconsole
(got the daemon the other times) and that one actually doesn't have the arguments, Xmx is 64m for thatVampire
08/21/2025, 1:04 PMVampire
08/21/2025, 1:04 PMgradlew
and gradlew.bat
Vampire
08/21/2025, 1:09 PMprintln(".".repeat(64 * 1024 * 1024))
does fail with OOME in the commandline.
But I get a nicer message and a proper stacktrace.Vampire
08/21/2025, 1:09 PMVampire
08/21/2025, 1:10 PMgradle-wrapper.jar
?Vampire
08/21/2025, 1:10 PMsha256sum gradle/wrapper/gradle-wrapper.jar
Philipp Nowak
08/21/2025, 1:11 PMPhilipp Nowak
08/21/2025, 1:11 PMPhilipp Nowak
08/21/2025, 1:11 PMVampire
08/21/2025, 1:11 PMPhilipp Nowak
08/21/2025, 1:12 PMVampire
08/21/2025, 1:12 PMLet me check where all the text output during configuration phase comes from in our projectMany output should not be a problem usually. I just thought maybe it is a very long line that busts the memory if the CLI reads it line by line from the daemon.
Vampire
08/21/2025, 1:15 PMJulien Plissonneau Duquène
08/21/2025, 1:19 PMVampire
08/21/2025, 1:36 PMVampire
08/21/2025, 1:38 PMVampire
08/21/2025, 1:39 PMVampire
08/21/2025, 1:39 PMpool-1-thread-1
actually has hit the OOME and produced that output.Vampire
08/21/2025, 1:40 PMJulien Plissonneau Duquène
08/21/2025, 1:41 PMPhilipp Nowak
08/21/2025, 1:43 PMPhilipp Nowak
08/25/2025, 7:19 AMPhilipp Nowak
08/25/2025, 7:19 AMPhilipp Nowak
08/25/2025, 8:50 AMTheGoesen
08/25/2025, 8:54 AMPhilipp Nowak
08/25/2025, 8:56 AMTheGoesen
08/25/2025, 8:58 AMPhilipp Nowak
08/25/2025, 9:01 AMTheGoesen
08/25/2025, 9:04 AMVampire
08/25/2025, 9:07 AMPhilipp Nowak
08/25/2025, 9:08 AMPhilipp Nowak
08/25/2025, 9:10 AMwc -L
, right? Then it would be 227, so not really longVampire
08/25/2025, 9:14 AM(1..1_000_000_000).forEach {
println("foo: $it")
}
After ~300_000 lines the daemon went OOM, the CLI was fine at 35 MiBTheGoesen
08/25/2025, 9:15 AMTheGoesen
08/25/2025, 9:15 AMTheGoesen
08/25/2025, 9:17 AMVampire
08/25/2025, 9:26 AM(1..1_000_000_000).forEach {
println("foo: $it")
}
snippet.
You can hardly send output faster to the CLI process from the daemon.
I'm at 4_500_000 messages right now and there is no problem on the CLI at all.
The CLI process oscillates between 20 and 50 MiB.
Only the daemon seems to have some leak, currently being at 12 GiB RAM.
But that could also be because it does not do a bigger garbage collection as still enough heap is available.Vampire
08/25/2025, 9:27 AMVampire
08/25/2025, 9:34 AMVampire
08/25/2025, 9:34 AMTheGoesen
08/25/2025, 9:39 AMval foo by tasks.registering {
doLast {
repeat(Int.MAX_VALUE) {
println()
repeat(5) {
print("$it aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
}
}
}
}
but if you bump 5 to 50 or something its too fastVampire
08/25/2025, 9:45 AMrepeat(Int.MAX_VALUE) {
println()
repeat(50) {
print("$it aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
}
}
is the same regarding how fast the output is given to the CLI as
repeat(Int.MAX_VALUE) {
println()
print((1..50).joinToString("") { "$it aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" })
}
if not even faster, because the whole string is given in one call?Vampire
08/25/2025, 9:49 AMTheGoesen
08/25/2025, 9:56 AMVampire
08/25/2025, 9:58 AMVampire
08/25/2025, 10:27 AMrepeat(Int.MAX_VALUE) {
repeat(50) {
print("$it aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n")
}
}
So this is some really annoying edge case I guess.Vampire
08/25/2025, 10:29 AMVampire
08/25/2025, 10:32 AMrepeat(Int.MAX_VALUE) {
println()
repeat(50) {
print("$it aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
}
}
runs wihout any problemsVampire
08/25/2025, 10:32 AMTheGoesen
08/25/2025, 10:56 AMmaybeFlushOutput
, which only flushes the output after 2 seconds(maybe) or after 30 s (unconditionally)
Not sure what happens when the OOME doesnt happen, I would guess either it gets so slow that the 2 s timeout hits or its supposed to always forward its output directlyTheGoesen
08/25/2025, 10:59 AMVampire
08/25/2025, 11:00 AM--conole=plain
.
I think with that there should be no grouping tried.Vampire
08/25/2025, 11:01 AMVampire
08/25/2025, 11:01 AMJulien Plissonneau Duquène
08/25/2025, 11:02 AMPhilipp Nowak
08/25/2025, 11:13 AMVampire
08/25/2025, 12:30 PMPhilipp Nowak
08/25/2025, 2:20 PMPhilipp Nowak
08/26/2025, 5:38 AM