Memory leaks in SonarQube Gradle plugin 2.7 and 2.6.2

gradle

(Eric Bruneton) #1
  • SonarQube Gradle plugin 2.7 and 2.6.2, Gradle 5.1.1
  • OutOfMemory error (Metaspace)
  • Repro steps: from commit 36ebc853a07054518c6b88eb03e8b465483c401b of https://gitlab.ow2.org/asm/asm, change sonar plugin version to 2.7 in build.gradle, and do “gradle/gradlew clean build test jacocoTestCoverageVerification uploadArchives sonarqube -Dsonar.host.url=<…>” a few times. The build crashes with an OutOfMemoryError.

An analysis of the memory dump with the Eclipse Memory Analyzer Tool shows a leak suspect in SonarQubePlugin.actionBroadcastMap. This is indeed a static hashmap which, if it is never cleaned (I haven’t looked at the code), will grow up indefinitely. This leak occurs even if the SonarQube tasks are not executed. It disappears only if the Gradle plugin is not applied at all to the Gradle projects.

This static hashmap was introduced in https://github.com/SonarSource/sonar-scanner-gradle/commit/e5da4f342a63163170c310f815260d192d0e5dbb. It was not there in the 2.6.2 version and this version does not have memory leaks when the Sonar gradle tasks are not executed.

However, there seems to be another leak affecting the 2.6.2 version. If you use the above repro steps, without changing the version to 2.7, you also get an OutOfMemory error after some time. This time the Eclipse Memory Analyzer Tool shows two leak suspects in

One instance of “com.persistit.JournalManager” loaded by “org.sonarsource.scanner.api.internal.IsolatedClassloader @ 0xe456e318” occupies 16 846 320 (14,91%) bytes. The memory is accumulated in one instance of “byte[]” loaded by “<system class loader>” .

and

One instance of “com.persistit.JournalManager$JournalCopier” loaded by “org.sonarsource.scanner.api.internal.IsolatedClassloader @ 0xe456e318” occupies 16 781 384 (14,85%) bytes. The memory is accumulated in one instance of “byte[]” loaded by “<system class loader>” .


(Lars Ködderitzsch) #2

I’ve just come to the same conclusion, the SonarQubePlugin.actionBroadcastMap retains references to the projects indefinitely, until gradle daemon heap memory is exhausted.

Even worse is that the sonarqube tasks doesn’t even need to run, the leak already happens when the plugin is merely configured.

This causes severe problems with larger multi-module projects, with gradle daemon going OOM after 2-3 build cycles.

Can this be fixed, please?


(Julien Henry) #3

Hi @ebruneton and @Lars

Thanks for reporting the issue. We’ll look at the issue with actionBroadcastMap. Regarding PersistIt, we finally managed to drop this dependency in SonarQube 7.7 so we won’t investigate this.


(Duarte Meneses) #5

Thanks for reporting this and submitting a fix. I’ve reviewed the P/R.


(Lars Ködderitzsch) #7

Thanks, for reference the PR located here: https://github.com/SonarSource/sonar-scanner-gradle/pull/53


(Duarte Meneses) #8

Merged. I’ve also created a ticket so that we can remove all objects from static fields.
https://jira.sonarsource.com/browse/SONARGRADL-61


(Lars Ködderitzsch) #9

I’m sorry, further testing revealed my fix to be incomplete.
Large memory structures (e.g. org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration are still being blocked by the action closures inside the actionBroadcastMap.


(Duarte Meneses) #10

Ok, thanks for the information. We will fix the ticket ASAP.