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

Wir verwenden Cookies, um unsere Webseite für Sie zu optimieren. Mit dem Besuch unserer Webseite erklären Sie sich damit einverstanden. // Our website is using cookies to improve your experience. By continuing to browse the site, you are agreeing to our use of cookies.

Weitere Informationen finden Sie in unserer Datenschutzerklärung. // For more information, please refer to our privacy policy.