Kotlin/Java Memory Leaks - jambit ToiletPaper

Kotlin / Java Memory Leaks

Problem: Memory leaks when using Kotlin and Java

When using Kotlin and Java, memory leaks can occur in combination with Java Lambdas. Example: a listener is created in Kotlin, which is then registered with a Java class and allegedly unregistered again:

public class Calculator {
    interface Listener {
        void onResult(int result);
    }
    Set<Listener> listeners = new HashSet<>();
    void addListener(Listener listener) {
        listeners.add(listener);
    }
    void removeListener(Listener listener) {
        listeners.remove(listener);
    }
    ...
}
fun main() {
    val c = Calculator()

    val listener = { sum: Int ->
        println("sum: $sum")
    }

    c.addListener(listener)
    c.removeListener(listener)
    c.sum(10, 20)
}

When running the Kotlin main-function you would not expect any output, but calling c.removeListener does not work as expected. To see the cause in the generated Java code, you can use Android Studio – click on "Tools → Kotlin → Show Kotlin Bytecode" followed by a click on "Decompile":

Object var10001 = listener;
if (listener != null) {
   var10001 = new MainKt$sam$test_Calculator_Listener$0(listener);
}
c.addListener((Listener)var10001);
var10001 = listener;
if (listener != null) {
   var10001 = new MainKt$sam$test_Calculator_Listener$0(listener);
}
c.removeListener((Listener)var10001);

listener is wrapped in MainKt$sam$test_Calculator_Listener$0(listener) each time before it is passed to addListener or removeListener, which then are two different Java objects.

Solution: Modifying the declaration of listener

The declaration of listener can slightly be modified by declaring the type to avoid the need for a generated wrapper:

val listener = Calculator.Listener {
  sum: Int -> println("sum: $sum")
}
c.addListener(listener)
c.removeListener(listener)
Listener listener = (Listener)null.INSTANCE;
c.addListener(listener);
c.removeListener(listener);
Kotlin / Java Memory Leaks vermeiden - jambit ToiletPaper

Further Aspects

---

Author: Marco Pfattner / Senior Software Architect/ Business Division Automotive Bavaria

Cookie Settings

This website uses cookies to personalize content and ads, provide social media features, and analyze website traffic. In addition, information about your use of the website is shared with social media, advertising, and analytics partners. These partners may merge the information with other data that you have provided to them or that they have collected from you using the services.

For more information, please refer to our privacy policy. There you can also change your cookie settings later on.

contact icon

Contact us now