Why is Gradle build of Kotlin source code pausing for ~3 secs "forcing System.gc()"? - performance

Every build takes an extra 3-4 seconds, pausing immediately after the log output prints the following.
[LIFECYCLE]
[org.jetbrains.kotlin.gradle.plugin.KotlinGradleBuildServices] Forcing
System.gc()
Why is it "forcing" this? How do I avoid this and speed up my build?

I've looked into this, and this is a consequence of having Gradle's debug-level logging enabled (eg. gradle --debug assemble).
Run Gradle without debug logging enabled (eg. gradle --info assemble) and this should not occur anymore.
References: libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt

Kotlin Gradle plugins calls System.gc before and after a build only when debug logging is enabled (Gradle is run with -d or --debug command line argument).
Users do not normally run Gradle with debug logging enabled because it is extremely noisy and slow, so forcing a GC is a relatively minor issue.
Historically this behaviour was added to test against memory leaks when Gradle daemon is enabled. The idea was to log a difference of used memory before and after a build, run a few builds consequently in a test, and assert that the difference is not exceeding the threshold.
I think calling System.gc should be avoided unless the test KotlinGradleIT#testKotlinOnlyDaemonMemory is running, so I've created an issue at Kotlin bugtracker https://youtrack.jetbrains.com/issue/KT-17960

Related

How can I enable Gradle Build Cache when running Gradle build with Coverity?

I have a simple Gradle project that has org.gradle.caching=true set in gradle.properties in order to enable the local build cache.
When I run the build directly (./gradlew clean build) I can see that the local build cache is being used: https://scans.gradle.com/s/ykywrv3lzik3s/performance/build-cache
However, when I run the build with Coverity (bin/cov-build --dir cov-int ./gradlew clean build) I see the build cache is disabled for the same build: https://scans.gradle.com/s/j2pvoyhgzvvxk/performance/build-cache
How is Coverity causing the build cache to be disabled, and is there a way to run a build with Coverity and the Gradle Build Cache?
You can't use the build cache with Coverity, or at least you don't want to.
The Gradle Build Cache causes compilation to be skipped:
The Gradle build cache is a cache mechanism that aims to save time by reusing outputs produced by other builds. The build cache works by storing (locally or remotely) build outputs and allowing builds to fetch these outputs from the cache when it is determined that inputs have not changed, avoiding the expensive work of regenerating them.
Were that mechanism to be used with Coverity, it would prevent cov-build from seeing the compilation steps, and hence it would be unable to perform its own compilation of the source code, which is a necessary prerequisite to performing its static analysis.
I don't know precisely how Coverity is disabling the cache (or if that is even intentional on Coverity's part), but if it didn't do so, then you would have to yourself, as described in the Synopsys article Cov-build using gradle shows "No files were emitted" error message, the key step of which is:
Use "clean" and "cleanBuildCache" task to remove all saved cache data which prevent full compilation.
before running cov-build.

"The input changes require a full rebuild for incremental task ':compileKotlin'." When Gradle building

Enviroment:
gradle-6.5.1
Kotlin
JSF
Hello everyone.
I had to move from Intellij because my licence expired And I was trying to buil my project using Gradle(As I was already doing before) using VS Code.
When I try to run my project with the usual gradle build -info --build-cache so when I try to compile my kotlin code it gets stack in the same part every single time:
> Task :compileKotlin
Deleting stale output file: C:\Users\Usuario\Desktop\cloud\build\classes\kotlin\main
Build cache key for task ':compileKotlin' is 3bd7d5460a493fb5a0944ec8a3be0e80
Task ':compileKotlin' is not up-to-date because:
No history is available.
The input changes require a full rebuild for incremental task ':compileKotlin'.
Using Kotlin/JVM incremental compilation
<-------------> 0% EXECUTING [4m 16s]
> :compileKotlin
It dosen't throw an error, it just stays like so for hours and hours.
I also updated from gradle-5.2.1(It didn't ork in that version neither) but when running the scan my gradle.build doesn't seem to have any problems, just some deprecated but still useful instructions: My scan results
Does anyone have an idea of what could be happening?

Why does my Kotlin Gradle build die with exit code 137?

We were seeing mysterious failures in our CI environment when running tests of a Kotlin code base.
gradle test compiled the code and the tests just fine. The tests ran and all appeared to pass. But then Gradle exited with code 137 (indicating it was killed with SIGKILL) and the CI system thus thought the build had failed.
Limiting the size of the JVM for Gradle didn't help. Nor did the --no-daemon and --max-workers options.
This is using Kotlin 1.2.40 and Gradle 4.3 on the Java 8 JVM.
The culprit in this case turned out to be the Kotlin compiler.
By default, the Kotlin compiler spawns a daemon in the background so that subsequent compilation jobs are faster. For a Kotlin code base of nontrivial size, this process can end up eating significant memory.
Its presence was causing Gradle to hit the memory limit on the CI container, and the Linux OOM killer was killing the Gradle process.
The solution: Tell the Kotlin compiler not to spawn the background process. This turns out to be a simple matter of setting an environment variable:
GRADLE_OPTS=-Dkotlin.compiler.execution.strategy=in-process
With that variable in place, Kotlin compilation runs inline in the Gradle JVM, and its data can thus be garbage-collected when Gradle moves on to running the tests.
It would also work to pass the option to the gradle command rather than setting it in the environment.

Launched gradle with a test with the --no-daemon parameter but the daemon is launched anyway

I'm trying to debug some unit tests I've written but the gradle daemon seems to always launch, ignoring any options I've set.
Using Mac OS X 10.9.5, Java 1.7, Gradle 2.2.1 and robolectric-gradle-plugin 0.14.1
Launching gradle with:
GRADLE_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5006"
./gradlew test --no-daemon -Dorg.gradle.debug=true
causes the following line to appear
To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: http://gradle.org/docs/2.2.1/userguid....
I've also tried setting the -Xdebug and Xrunjdwp as jvmArgs in build.gradle.
Nothing else happens but if I add -d and rerun, it turns out that the daemon has launched and is waiting on port 5005 for a debugger: http://pastebin.com/TqaXubmr
Finally, if I then launch a debugger attaching to port 5005 the tests run but none of the breakpoints are hit.
The gradle.properties is empty, I haven't set org.gradle.jvmargs.
You might have configure memory settings in your gradle.properties? these can force gradle to launch a new jvm as these settings cannot be applied dynamically.
Keep in mind that unit tests are always executed in a separate jvm. The easiest way to debug tests executed by gradle is to run
>gradle :test --debug-jvm
this will automatically configure your test task to run with debug enabled.

Improve gradle startup time with groovyserv or nailgun or what

I'm trying to improve the startup time of Gradle. The expererimental --daemon switch doesn't seem to really speed it up. So I'm thinking to use some server process independent of gradle, and make gradle connect to it. The options I found so far are
nailgun to invoke java
GroovyServ to invoke a groovy script
Since gradle is started by a shell script, it takes some tweaking. My question is: has anyone used the above options to start gradle? Or if you have successfully used another option, what's that?
My guess is that your build is doing something at configuration time that it should be doing at execution time. With m5, gradle build --profile will give you an HMTL report showing where the time goes. Another way to see what's going on is gradle build --info or gradle build --debug.

Resources