Session

Two Garbage Collectors Walk Into a Process

Two garbage collectors walk into a process. Neither picks up the rubbish.

I built a tool that turns Kotlin libraries into NuGet packages. From C#, you add a package and call a method. Behind that method is another runtime, another heap, and another garbage collector. Oops, I had doubled the number of garbage collectors. Surely memory management was now extra automatic, right?

This talk follows what happened next: a method that worked until it threw an exception, a Kotlin object whose lifetime depended on a C# `using`, and callbacks that meant both runtimes could now hold on to each other's objects. Eventually, I'd built the memory-management equivalent of a rubbish pile on the boundary between two councils. Both had a collection service. Neither would touch it. Each runtime saw references from the other side and kept the objects alive, long after the application had finished with them.

We'll trace the collection routes on both sides of that boundary, using heap dumps to see what's still waiting to be picked up. We'll look at how a Debug build gave a lifetime test the wrong reason to pass, then sort out who's responsible for taking out what. That means handles, explicit ownership, and tests that check the rubbish actually gets collected.

You don't need to know Kotlin. Hell you don't even need to know all of C#. If you've ever wrapped a native library or wondered what `using var` actually does for you, you'll leave with concrete ways to make ownership explicit and test that objects really get collected. And perhaps a little less enthusiasm for adding a second garbage collector.

Isuru Rajapakse

Motorola Solutions, Android Developer

Melbourne, Australia

Actions

Please note that Sessionize is not responsible for the accuracy or validity of the data provided by speakers. If you suspect this profile to be fake or spam, please let us know.

Jump to top