Size the daemon heaps from measurement, and add the script that measures them - #157
Merged
Merged
Conversation
…t measures them The earlier 4g was reasoning from a reference machine, not evidence, and it was wrong for a 16 GB laptop that also runs an emulator and a browser. Measured with scripts/measure-jvm-memory.sh against assembleDebug: heap wall live set GC overhead swapped 2g 39.3s 1621 MB 38.1% 955 MB 3g 33.3s 1608 MB 24.9% 40 MB <- chosen 4g 36.3s 1599 MB 23.7% 326 MB The old 2048m sat at 1.26x a ~1.6 GB live set and spent 38% of the build in GC, so raising it was right. But 4g is slower than 3g on this machine: it wins marginally on GC and loses on swap, because the extra heap comes out of the same 16 GB the emulator is using. The script is the point rather than the numbers, which are a property of the machine and not of the project. It sweeps candidate heaps and reports the three things that actually decide the answer - live set (the floor), GC overhead, and swap delta (the ceiling the usual advice ignores) - then prints the properties to paste. Run it again on different hardware instead of copying these values. Two traps it had to handle: the GC log must be read from a byte offset rather than deleted between the warm-up and measured runs, because the daemon holds it open and deleting it makes every GC figure read as zero; and each candidate needs its own daemon or it measures the previous heap.
simtop
force-pushed
the
refactor/jacoco-root-report-and-build-tuning
branch
from
August 9, 2026 13:20
dc509f8 to
11621ac
Compare
simtop
enabled auto-merge (squash)
August 9, 2026 13:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #156, which set the daemon heaps by reasoning rather than measurement. This measures them, and adds the script that did it.
The measurement
scripts/measure-jvm-memory.sh 2g 3g 4gagainstassembleDebugon a 16 GB machine with the usual emulator and browser open:Two things that settles.
Raising it from 2g was right. The live set is ~1.6 GB, so
-Xmx2048mwas running at 1.26x — under the 1.5–2x a collector needs to stay out of the way — and paying 38% of the build in GC.But 4g was wrong. It wins marginally on GC and loses on everything else: it swaps 8x more and finishes 3s slower. The extra gigabyte comes out of the same 16 GB the emulator and browser are using. More heap stops being more speed once the machine, not the JVM, is the constraint — which is exactly what the usual "4g on a 16 GB box" advice misses, because it assumes the build is the only thing running.
The script is the actual deliverable
The numbers above are a property of this machine, not of the project, so they should not be copied anywhere.
scripts/measure-jvm-memory.shsweeps candidate heaps and reports the three things that decide the answer:It prints the exact properties to paste. Run it on new hardware instead of copying these values.
Two traps it had to handle, both of the "measurement silently returns nothing" kind:
./gradlew --stopfirst), or it measures the previous heap setting.On the Kotlin daemon
kotlin.daemon.jvmargswas previously unset entirely, so the JVM that every module's Kotlin compilation runs through took whatever default the plugin chose. It is now set explicitly, and setting it explicitly is the point — the specific 1536m is not yet measured, and the comment ingradle.propertiessays so. A separate sweep for it is in progress; the first attempt produced numbers I do not trust, so it is deliberately not being asserted here.Verification
make build-budgetre-run cleanly on the final settings (the run made during #156 was contaminated —gradle.propertieswas edited inside its measurement window):All budgets met. The cold figure is well under the 37s recorded in ADR 0011, but its 115% spread is too wide to claim that as an improvement rather than noise; the stable result is the 0.99x deep/leaf ratio, unchanged.