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?