question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Memory leaked every time `formatKotlin` task is run

See original GitHub issue

It seems like each invocation of formatKotlin leaks tens of MiB of heap on a small codebase (2500loc). This is using Gradle 7.0 with kotlinter 3.4.4 and kotlin 1.5.0.

Here’s the sequence of output from the class histogram (obtained via jcmd 15861 GC.run && jcmd 15861 GC.class_histogram | grep kotlin | head) after running the formatKotlin task several times, capturing the histogram after each run:

% jcmd 15861 GC.run && jcmd 15861 GC.class_histogram | grep kotlin | head
15861:
Command executed successfully
   3:        502184       16069888  org.jetbrains.kotlin.name.FqNameUnsafe
   4:        502184       12052416  org.jetbrains.kotlin.name.FqName
   5:        502183       12052392  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Exports
   9:        236643        5679432  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Requires
  10:        228052        5473248  org.jetbrains.kotlin.cli.jvm.modules.CoreJrtVirtualFile
  13:         93720        2249280  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Explicit
  14:         93720        2249280  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Root
  15:         93720        2249280  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
  22:         17219         964264  org.jetbrains.kotlin.com.intellij.openapi.extensions.impl.InterfaceExtensionPoint
  23:         39831         955944  org.jetbrains.kotlin.cli.jvm.index.JavaRoot
% jcmd 15861 GC.run && jcmd 15861 GC.class_histogram | grep kotlin | head
15861:
Command executed successfully
   3:        547837       17530784  org.jetbrains.kotlin.name.FqNameUnsafe
   4:        547837       13148088  org.jetbrains.kotlin.name.FqName
   5:        547836       13148064  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Exports
   9:        258156        6195744  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Requires
  10:        248784        5970816  org.jetbrains.kotlin.cli.jvm.modules.CoreJrtVirtualFile
  13:        102240        2453760  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Explicit
  14:        102240        2453760  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Root
  15:        102240        2453760  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
  22:         18781        1051736  org.jetbrains.kotlin.com.intellij.openapi.extensions.impl.InterfaceExtensionPoint
  23:         43452        1042848  org.jetbrains.kotlin.cli.jvm.index.JavaRoot
% jcmd 15861 GC.run && jcmd 15861 GC.class_histogram | grep kotlin | head
15861:
Command executed successfully
   3:        593490       18991680  org.jetbrains.kotlin.name.FqNameUnsafe
   4:        593490       14243760  org.jetbrains.kotlin.name.FqName
   5:        593489       14243736  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Exports
   9:        279669        6712056  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Requires
  10:        269516        6468384  org.jetbrains.kotlin.cli.jvm.modules.CoreJrtVirtualFile
  13:        110760        2658240  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Explicit
  14:        110760        2658240  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Root
  15:        110760        2658240  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
  22:         20343        1139208  org.jetbrains.kotlin.com.intellij.openapi.extensions.impl.InterfaceExtensionPoint
  23:         47073        1129752  org.jetbrains.kotlin.cli.jvm.index.JavaRoot
% jcmd 15861 GC.run && jcmd 15861 GC.class_histogram | grep kotlin | head
15861:
Command executed successfully
   3:        639143       20452576  org.jetbrains.kotlin.name.FqNameUnsafe
   4:        639143       15339432  org.jetbrains.kotlin.name.FqName
   5:        639142       15339408  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Exports
   9:        301182        7228368  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Requires
  10:        290248        6965952  org.jetbrains.kotlin.cli.jvm.modules.CoreJrtVirtualFile
  13:        119280        2862720  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Explicit
  14:        119280        2862720  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Root
  15:        119280        2862720  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
  21:         21905        1226680  org.jetbrains.kotlin.com.intellij.openapi.extensions.impl.InterfaceExtensionPoint
  22:         50694        1216656  org.jetbrains.kotlin.cli.jvm.index.JavaRoot

Here’s the same type of data, this time on a fresh daemon (./gradlew --stop && ./gradlew classes to create a warmed up daemon), then showing the first two invocations of formatKotlin.

% jcmd 16318 GC.run && jcmd 16318 GC.class_histogram | grep kotlin | head
16318:
Command executed successfully
  17:          5254         210160  kotlin.reflect.jvm.internal.impl.protobuf.SmallSortedMap$1
  21:          1817         159896  kotlin.reflect.jvm.internal.impl.metadata.ProtoBuf$Type
  26:          5254         126096  kotlin.reflect.jvm.internal.impl.protobuf.FieldSet
  33:          1072          94336  kotlin.reflect.jvm.internal.impl.metadata.ProtoBuf$Function
  42:          1203          76992  kotlin.reflect.jvm.internal.impl.metadata.ProtoBuf$ValueParameter
  47:          2570          61680  kotlin.reflect.jvm.internal.impl.name.Name
  49:          2478          59472  kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal
  58:           515          45320  kotlin.reflect.jvm.internal.impl.metadata.ProtoBuf$Property
  62:          1226          39232  kotlin.reflect.jvm.internal.impl.name.FqNameUnsafe
  70:           847          33880  kotlin.reflect.jvm.internal.impl.metadata.jvm.JvmProtoBuf$JvmMethodSignature
% jcmd 16318 GC.run && jcmd 16318 GC.class_histogram | grep kotlin | head
16318:
Command executed successfully
   8:         45654        1460928  org.jetbrains.kotlin.name.FqNameUnsafe
  10:         45654        1095696  org.jetbrains.kotlin.name.FqName
  11:         45653        1095672  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Exports
  19:         21513         516312  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Requires
  20:         20732         497568  org.jetbrains.kotlin.cli.jvm.modules.CoreJrtVirtualFile
  26:          5535         221400  kotlin.reflect.jvm.internal.impl.protobuf.SmallSortedMap$1
  27:          8520         204480  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Explicit
  28:          8520         204480  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Root
  29:          8520         204480  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
  32:          1976         173888  kotlin.reflect.jvm.internal.impl.metadata.ProtoBuf$Type
% jcmd 16318 GC.run && jcmd 16318 GC.class_histogram | grep kotlin | head
16318:
Command executed successfully
   4:         91307        2921824  org.jetbrains.kotlin.name.FqNameUnsafe
   6:         91307        2191368  org.jetbrains.kotlin.name.FqName
   7:         91306        2191344  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Exports
  14:         43026        1032624  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo$Requires
  15:         41464         995136  org.jetbrains.kotlin.cli.jvm.modules.CoreJrtVirtualFile
  24:         17040         408960  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Explicit
  25:         17040         408960  org.jetbrains.kotlin.resolve.jvm.modules.JavaModule$Root
  26:         17040         408960  org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
  30:          5535         221400  kotlin.reflect.jvm.internal.impl.protobuf.SmallSortedMap$1
  32:          3161         177016  org.jetbrains.kotlin.com.intellij.openapi.extensions.impl.InterfaceExtensionPoint

I’ve attached a heap graph created with my heap analysis tools in case that’s instructive. It’s clear that there are a whole lot of PicoContainers being made, among other kotlin internal classes, so perhaps there is some reference being cached when it shouldn’t be either in the plugin or in ktlint itself?

gradle daemon heap graph.svg.gz

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
jeremymailencommented, May 27, 2021

I haven’t forgotten about this issue, but I haven’t had the chance to delve into the guts of ktlint where the leak most likely is. hiding. I have a feeling, not scientific whatsoever, that ktlint is going to spin a new release soon upgrading to kotlin 1.5 and this leak will be fixed. I could be wrong though.

1reaction
marshallpiercecommented, May 11, 2021

I made a teeny tiny repro project: https://github.com/marshallpierce/kotlinter-leak-repro

With less code it leaks more slowly but it’s still leaking (easily visible with GC.class_histogram).

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to get rid of memory leaks? A practical approach using ...
D LeakCanary: LeakCanary is running and ready to detect leaks. How does it work ? Once installed, LeakCanary automatically detects and reports memory...
Read more >
valgrind memory leak detector Code Example
Answers related to “valgrind memory leak detector”. how to use valgrind · linux command to check memory usage in percentage · check ram...
Read more >
java - Can a scheduled future cause a memory leak?
The solution for this problem is to either write your own Future implementation or to call the purge() method every now and then....
Read more >
Out of memory a few minutes after startup
JENKINS-23762Adding a mixin class to Job leaks memory from every DSL run · Bug. JENKINS-23706Plugin Memory Leak : OutOfMemoryError : PermGen ...
Read more >
mozilla-central: pushlog
aa124b39d3e5d236979e61bd911782a60fa871ea, Mike Hommey — Bug 1797891 - Make some tasks really only run on m-c or autoland. r=jcristau. nfay@mozilla.com
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found