21 03 2013
- Create without dispose EventHandler – “Closure objects of type EventHandler provide a simple mechanism to group all events and listeners associated with an object together. This allows for easy removal of listeners when the events being listened to can no longer ﬁre. Unfortunately this is also one of the main sources of leaks“
- Undisposed member object has EventHandler as member
- Object graveyard (holding onto objects in a persistent structure like a list/dictionary so objects can’t ever get collected)
- Overwriting EventHandler ﬁeld in derived class. – “Closure implements inheritance using a prototype-based approach , which can break the expectations of programmers coming from a more standard OOP language background (such as C++ or Java). For EventHandlers this can cause memory leaks as the overwritten EventHandler cannot be freed .“
- Unmatched listen/unlisten calls. – “The semantics of the listen and unlisten calls require all parameters to be the same. When the parameters do not match, the event listener is not removed and a reference to objects being listened remains, inhibiting the garbage disposal.“
- Local EventHandler – “A local EventHandler instance that does not escape scope, e.g., a locally deﬁned variable that is not assigned to a ﬁeld member, added to an array, or captured in a closure, can not be disposed of later.“
Other pitfalls of their current analysis include
- Not tracking objects with fully qualified names (such as application.window.toolbar)
- Objects that are never returned
- Objects not captured in closures
- Not checking of double disposal
Still, it’s an impressive feat.
A couple other neat points came up, such as that the
delete keyword doesn’t actually delete memory. It only deletes properties of an object. Just to double check that we found ourselves at the mozilla dev site which had this hilariously appropriate quote on the page for the
The delete operator removes a property from an object. Unlike what common beliefs suggests, the delete operator has nothing to do with directly freeing memory (it only does indirectly via breaking references.
The ultimate way to avoid memory leaks is to be cognizant of who uses what, who holds on to what, and what needs to be removed when.