Memory leak in sonarqube gradle plugin

Hi i was investigate multimodule project memory leek exhastion of metaspace. I was looking why build with gradle take so much metaspace and findings:
You execute in custom classloader which is ok, but its not properly shutdown jGIT so classpath is reference so classes can be unloaded because are referenced by running thread and application shutdown hook, also looking into memory dump with eclipse mat i have this allocaiton on heap which should not be there:

The classloader/component „org.sonar.classloader.ClassRealm @ 0xcacc1378“ occupies 35 571 056 (11,06 %) bytes. The memory is accumulated in one instance of „com.sonar.security.config.C“, loaded by „org.sonar.classloader.ClassRealm @ 0xcacc1378“, which occupies 33 318 960 (10,36 %) bytes. 

Because com.sonar.security.config.C is propertierary or obfuscated i dont look into it.

also when i look into path to gc for sonar classloader used in i get this class which force to keep classes in metaspace:

Class Name                                                                                                                              | Shallow Heap | Retained Heap
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
org.sonarsource.scanner.api.internal.IsolatedClassloader @ 0xcc93be08                                                                   |           96 |     1 266 680
|- contextClassLoader jdk.internal.net.http.HttpClientImpl$SelectorManager @ 0xc42bb518  HttpClient-2-SelectorManager JNI Global, Thread|          144 |         4 160
|- contextClassLoader java.lang.Thread @ 0xc43679f0  OkHttp TaskRunner JNI Global, Thread                                               |          112 |           272
|- contextClassLoader okio.AsyncTimeout$Watchdog @ 0xc4368340  Okio Watchdog JNI Global, Thread                                         |          112 |           240
|- <classloader> class okio.AsyncTimeout$Watchdog @ 0xc43682b8                                                                          |            8 |            32
|- <classloader> class okio.AsyncTimeout @ 0xcc2b3780                                                                                   |           32 |           112
|- <classloader> class okio.AsyncTimeout$Companion @ 0xcc2b3a00                                                                         |            8 |            32
|- <classloader> class okhttp3.internal.concurrent.TaskRunner @ 0xcc6ceed0                                                              |           16 |            88
|- <classloader> class okhttp3.internal.concurrent.TaskRunner$RealBackend @ 0xcc6cf0b8                                                  |            8 |            40
|- <classloader> class okhttp3.internal.concurrent.TaskRunner$runnable$1 @ 0xcc6cf508                                                   |            8 |            40
|- <classloader> class okio.SocketAsyncTimeout @ 0xcc813828                                                                             |            8 |            40
|- classloader java.security.ProtectionDomain @ 0xc4374d68                                                                              |           40 |           656
|- <classloader> class okhttp3.internal.Util$$Lambda$4215+0x0000027e118ecc80 @ 0xcc6cf240                                               |            0 |             0
|- <classloader> class okhttp3.internal.concurrent.TaskQueue @ 0xcc6cf5a8                                                               |            8 |            72
|- <classloader> class org.eclipse.jgit.lib.RepositoryCache$$Lambda$4374+0x0000027e11a95190 @ 0xc429a528                                |            0 |             0
'- <classloader> class org.eclipse.jgit.lib.internal.WorkQueue$2 @ 0xccb143f0                                                           |            0 |             0
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

I suggest that you fix embeded scanner that can be runned 100 times on simple java projects which resides in git or you add option to execute for each module as separated process so you dont polute gradle daemon memory.

Hey there.

What version of SonarQube are you using, and which version of the SonarScanner for Gradle (the gradle plugin)?

I used latest stable gradle plugin 4.4.1.3373. Checkout repo switch to the tag (4.4.1.3373) and sonar ube 9.9.1 (developer licence). We have like 25 apps in build its monorepo becasue its different app so different projects in sonarqube so 25 calls of embeded scanner after each call metaspace incrased to arround 150MB (this increase is slightly les then with 4.3.x plugin) and i was looking why isolated classloader is preserved and there is jgit which add shutdown hook (which you can’t remove directly also in latest master version. I try it to remove this hook via debuger but when i removed there come this list of gc path for this classloader. Problem is that after running 10 time we don;t have enough metaspace and we give 1.5GB . So it will be good if its provided option for gradle plugin to execute different process for scanning. Probably I will look into it and create pull request if we add more app into our monorepo.