在我的bootstrap.js
的顶部我定义了一堆lazyGetter
s,而不是 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) });
我听说你必须 unload
导入的模块。但是您为 lazyGetter
创建的“模块”又如何呢?是?我该如何卸载那些?我会做一个delete myServices
?
如果我做 delete
上myServices
这是全局变量,这是否意味着我应该在卸载时删除所有全局变量?
我在这里读到: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"); }
block 引用>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.
最佳答案
您提供的代码没有导入模块,而是定义了服务 getter,所以没问题。
(旁白:还有一个 XPCOMUtils.defineLazyServiceGetter
helper ...)
但是如果你做了这样的事情:
XPCOMUtils.defineLazyGetter(myServices, 'SomeSymbol', function() {
return Cu.import("chrome://myaddon/content/mymodule.jsm", {}).SomeSymbol;
});
那么您当然需要再次 Cu.unload()
该模块。最好通过注册模块在加载后立即卸载来完成此操作(IMO),例如:
XPCOMUtils.defineLazyGetter(myServices, 'SomeSymbol', function() {
let rv = Cu.import("chrome://myaddon/content/mymodule.jsm", {}).SomeSymbol;
unload(function() {
Cu.unload("chrome://myaddon/content/mymodule.jsm");
});
return rv;
});
其他人只是主动卸载所有可能已导入或未导入的模块。这很好,因为 Cu.unload()
未导入的模块不会执行任何操作。
PS:将某些内容插入另一个模块时,您仍然可能会遇到麻烦,例如。
XPCOMUtils.defineLazyServiceGetter(Services /* other module */,
'sss',
'@mozilla.org/content/style-sheet-service;1',
'nsIStyleSheetService');
在此示例中,XPCOMUtils.jsm
可能仍会引用从代码中作为参数传递的字符串,从而泄漏您的代码。 (此外,将内容粘贴到不属于您自己的模块中是相当粗鲁的,并且可能会与执行相同操作的其他附加组件产生冲突。)
关于javascript - 在引导插件中卸载惰性 setter/getter ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24879400/