Skip to content

Why the collector keeps them

The situation

A desktop application grows from 200 MB to 3 GB over a working day and is restarted every evening.

A heap dump shows 40,000 instances of OrderPanel. The application has one order panel open at a time, and the user has opened perhaps forty in the day.

Every retained OrderPanel is reachable through the same chain:

EventBus (static) -> listeners (ArrayList) -> OrderPanel$1 -> this$0 -> OrderPanel

The panel registers itself in its constructor:

java EventBus.subscribe(new PriceListener() { public void onPrice(Price p) { refresh(p); } // captures OrderPanel });

There is no matching unsubscribe anywhere in the class.

The panels are closed and the user cannot see them. Why does the garbage collector not reclaim them?