At the top of my bootstrap.js
I define a bunch of lazyGetter
s, instead of a JSM:
const myServices = {};
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
XPCOMUtils.defineLazyGetter(myServices, 'sss', function(){ return Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService) });
I heard that you have to unload
imported modules. But what about "modules" that you create for lazyGetter
s? How would I unload those? Would I do a delete myServices
?
If I do a delete
on myServices
which is a global, does that mean I should delete all my global variables on unload?
I read here: Forgetting to unload JavaScript modules in restartless add-ons
Forgetting to unload JavaScript modules in restartless add-ons
Another common cause of leaks is forgetting to unload JavaScript code modules in bootstrapped add-ons. These leaks cannot be detected by looking at about:compartments or about:memory because such modules live within the main System compartment.
Also, when your add-on gets updated and re-enabled, the previous module version that is still loaded will be used, which might break your add-on entirely.
The following example shows how to unload your modules again (bootstrap.js):
Components.utils.import("resource://gre/modules/Services.jsm"); function startup(data, reason) { // This assumes your add-on did register some chrome Components.utils.import("chrome://myaddon/content/mymodule.jsm"); } function shutdown(data, reason) { if (reason != APP_SHUTDOWN) { // No need to do regular clean up when the application is closed // unless you need to break circular references that might negatively // impact the shutdown process. return; } // Your add-on needs to unload all modules it ships and imported! Components.utils.unload("chrome://myaddon/content/mymodule.jsm"); }
Note: Modules not belonging to your add-on — such as Services.jsm — should not be unloaded by your add-on, as this might cause errors and/or performance regressions and will actually increase the memoryusage.
The code you provided does not import a module, but defines a service getter, so it is fine.
(Aside: there is also a
XPCOMUtils.defineLazyServiceGetter
helper...)However if you did something like this:
then of course you'd need to
Cu.unload()
that module again. This is best done (IMO) by registering the module to unload as soon as it is loaded, so something like:Other people just pro-actively unload all modules that could have been potentially imported or not. This is fine to, as
Cu.unload()
ing a module that wasn't imported just does nothing.PS: You can still run into trouble when sticking something into another module, like.
In this example
XPCOMUtils.jsm
might still reference the strings passed as arguments from your code and hence leak your code. (Also, it is rather rude to stick stuff into modules that aren't your own and may create conflicts with other add-ons doing the same thing.)