Using strong references for window objects or their descendants
Consider using WeakMap instead of Map for example
Consider using objRef = Components.utils.getWeakReference(obj) instead of objRef = obj.
Ensure not only that all add/remove listeners are balanced, but that they point to the exact same reference(s) for add as they do for remove.
Ex: Use of bind() and anonymous arrow functions both create a new reference for a listener.
const listenerRef = listener.bind(this);
// objRef should also be the exact same reference for add and remove
objRef.addEventListener(listenerRef);
objRef.removeEventListener(listenerRef);
Handle the case when a listener fires just before or just as the addon is shutting down.
Consider having a state variable for isShuttingDown that is checked for an early return from the listener, so you prevent the possibility creating a reference that has already been cleaned up.
On shutdown, remove any remaining references to window objects or their descendants by explicitly setting them to null or deleting them altogether.
Referencing #88 solutions
Things I've found that cause leaks:
WeakMap
instead ofMap
for exampleobjRef = Components.utils.getWeakReference(obj)
instead ofobjRef = obj
.add
as they do forremove
.bind()
and anonymous arrow functions both create a new reference for a listener.isShuttingDown
that is checked for an early return from the listener, so you prevent the possibility creating a reference that has already been cleaned up.null
or deleting them altogether.Resources and general notes
Resources Here's a great MDN page on common causes for memory leaks in extensions.
Here's a blog article I was referred to about what to take care of during clean up in a Bootstrap extension.
Notes You must use a "debug" build of Firefox to test locally for memory leaks.
91 provides a helper script to test locally
Debugging [unit] test tips and tricks