mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-29 23:27:44 +00:00
One Kotlin daemon reused across many builds (switching -PquartzDir on and off) filled its 6g heap and spent 35 min in back-to-back full GCs at 400% CPU without finishing: the JVM's default overhead limit only gives up at 98% of time in GC. kotlin.daemon.jvmargs now sets ParallelGC's limit to 50% of time with under 10% of the heap freed, plus ExitOnOutOfMemoryError, so such a daemon exits; the Kotlin plugin compiles the task in the Gradle daemon (its fallback strategy) and the next build starts a fresh daemon. Measured: a cold build peaks near 5% of the time in GC, far from the limit. Starving a 4g daemon on a cold :commonsUI build made it exit after about a minute of 90%+ GC, and the build carried on in the fallback. The 6g heap is unchanged. AGENTS.md: stop both daemons when switching -PquartzDir (./gradlew --stop leaves the Kotlin daemon running). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NQ76C61q1cALxjPX98gPg4
68 lines
4.5 KiB
Properties
68 lines
4.5 KiB
Properties
# Project-wide Gradle settings.
|
|
# IDE (e.g. Android Studio) users:
|
|
# Gradle settings configured through the IDE *will override*
|
|
# any settings specified in this file.
|
|
# For more details on how to configure your build environment visit
|
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
|
# Specifies the JVM arguments used for the daemon process.
|
|
# The setting is particularly useful for tweaking memory settings.
|
|
org.gradle.jvmargs=-Xmx6g -Dfile.encoding=UTF-8
|
|
# When configured, Gradle will run in incubating parallel mode.
|
|
# This option should only be used with decoupled projects. More details, visit
|
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
|
org.gradle.parallel=true
|
|
org.gradle.caching=true
|
|
# AndroidX package structure to make it clearer which packages are bundled with the
|
|
# Android operating system, and which are packaged with your app's APK
|
|
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
|
android.useAndroidX=true
|
|
# Kotlin code style for this project: "official" or "obsolete":
|
|
kotlin.code.style=official
|
|
# Enables namespacing of each library's R class so that its R class includes only the
|
|
# resources declared in the library itself and none from the library's dependencies,
|
|
# thereby reducing the size of the R class for that library
|
|
android.nonTransitiveRClass=true
|
|
android.enableR8.fullMode=true
|
|
|
|
# 6g, down from 8g (metaspace stays 2g). Beside the Gradle daemon's 6g and the test JVMs, 8g let the
|
|
# Kotlin daemon reach 8.9 GB resident, and the OOM killer took it (or the Gradle daemon, or a test
|
|
# JVM) in most incremental pre-push runs on a 16 GB machine. 4g is too little: a cold build
|
|
# compiles :commonsUI for the JVM and Android in this one daemon at once, and at 4g it spent 977 s
|
|
# in full GCs and stalled. At 6g a cold pre-push run spends 43 s in full GCs and all JVMs peak
|
|
# near 10.5 GB. A bigger machine can raise it in ~/.gradle/gradle.properties, which wins over
|
|
# this file; CI sets its own cap in .github/workflows/build.yml.
|
|
#
|
|
# The GC flags make a hopeless Kotlin daemon exit instead of grinding. Gradle reuses one daemon
|
|
# across builds, and one fed many of them (switching -PquartzDir on and off) filled its heap with
|
|
# their state: it spent 35 min in back-to-back full GCs at 400% CPU without finishing, because the
|
|
# JVM's default limit only gives up at 98% of time in GC. With these, once full GCs take over half
|
|
# the time and free under a tenth of the heap, the daemon throws OutOfMemoryError and exits; the
|
|
# Kotlin plugin then compiles the task in the Gradle daemon (its fallback strategy), and the next
|
|
# build starts a fresh daemon. A cold build stays well clear: at its peak (:commonsUI for Android)
|
|
# it spends about 5% of the time in GC. Checked by starving a 4g daemon on a cold :commonsUI build:
|
|
# it exited after about a minute of 90%+ GC and the build carried on in the fallback.
|
|
kotlin.daemon.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=2g -XX:+UseParallelGC -XX:GCTimeLimit=50 -XX:GCHeapFreeLimit=10 -XX:+ExitOnOutOfMemoryError
|
|
|
|
# because we use a custom jvmAndroid target
|
|
kotlin.mpp.applyDefaultHierarchyTemplate=false
|
|
|
|
# This is needed for the Swift bridge to work.
|
|
kotlin.mpp.enableCInteropCommonization=true
|
|
# Incremental compilation for the KMP modules. Since K2, Kotlin rebuilds a whole KMP module
|
|
# whenever a recompiled file sits in a shared source set (commonMain, jvmAndroid): the guard
|
|
# for KT-62686, still in 2.5.0-Beta1. Nearly all of :commons and :commonsUI is shared, so every
|
|
# edit paid a full rebuild: a body change in :commons took ~39 s, a new public declaration
|
|
# ~161 s (commons, commonsUI and the app); with this, ~10 s and ~26 s. The risk the guard
|
|
# covers is narrow: common code resolving a platform declaration that shadows a dependency's
|
|
# class of the same name, which can give a wrong incremental result locally (a clean build
|
|
# fixes it). CI and release builds start clean, so they are unaffected.
|
|
kotlin.internal.incremental.enableUnsafeOptimizationsForMultiplatform=true
|
|
# Enabled parallel sync for Gradle 9.4+
|
|
org.gradle.tooling.parallel=true
|
|
# Apple test tasks (iosSimulatorArm64Test, macosArm64Test) can only run on a Mac; on Linux and
|
|
# Windows hosts KGP disables them and warned about it on every configuration. That is expected
|
|
# here (CI runs them on macos-latest), so the warning carries no signal. Note the flag silences
|
|
# every disabled-native-target notice, not only those: if a host ever loses the ability to
|
|
# compile an Apple target, that is quiet too. CI's macOS jobs are where Apple code is verified.
|
|
kotlin.native.ignoreDisabledTargets=true
|