在bootstrap.js
的顶部,我定义了一堆lazyGetter
,而不是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
忘记在无重启加载项中卸载JavaScript模块
泄漏的另一个常见原因是忘记卸载JavaScript代码 bootstrapped加载项中的模块。无法检测到这些泄漏 看看:隔间或左右:内存,因为这样的模块 住在主系统隔间内。
此外,当您的加载项更新并重新启用时,前一个 将使用仍然加载的模块版本,这可能会中断 你的加载项完全。
以下示例说明如何再次卸载模块 (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"); }
注意:不属于您的加载项的模块(例如Services.jsm)不应由您的加载项卸载,因为这可能会导致错误和/或性能回归,并且实际上会增加内存使用量。
答案 0 :(得分:2)
您提供的代码不会导入模块,而是定义服务获取器,所以没关系。
(旁白:还有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
可能仍会引用从代码中作为参数传递的字符串,从而泄露代码。 (此外,将内容粘贴到不属于您自己的模块中可能会非常粗鲁,并且可能会与其他附加组件发生冲突,从而做同样的事情。)