|
那么我们的课题就是,如何让老模块的代码更新后,确保没有对象保持了模块的引用。首先我们以 如何更新模块代码 一节中的代码为例,看看老模块资源不回收会出现什么问题。为了让结果更显著,我们修改一下 code.js
// code.js var array = [];
for (var i = 0; i < 10000; i++) { array.push('mem_leak_when_require_cache_clean_test_item_' + i); }
module.exports = array;
// app.js function cleanCache (module) { var path = require.resolve(module); require.cache[path] = null; }
setInterval(function () { var code = require('./code.js'); cleanCache('./code.js'); }, 10);
好~我们用了一个非常笨拙但是有效的方法,提高了 router.js 模块的内存占用,那么再次启动 main.js 后,就会发现内存出现显著的飙升,不到一会 Node.js 就提示 process out of memory。然而实际上从 app.js 与 router.js 的代码中观察的话,我们并没发现哪里保存了旧模块的引用。
我们借助一些 profile 工具如 node-heapdump 就可以很快的定位到问题所在,在 module.js 中我们发现 Node.js 会自动为所有模块添加一个引用
function Module(id, parent) { this.id = id; this.exports = {}; this.parent = parent; if (parent && parent.children) { parent.children.push(this); }
this.filename = null; this.loaded = false; this.children = []; }
因此相应的,我们可以调整一下cleanCache函数,将这个引用在模块更新的时候一并去除。
// app.js function cleanCache(modulePath) { var module = require.cache[modulePath]; // remove reference in module.parent if (module.parent) { module.parent.children.splice(module.parent.children.indexOf(module), 1); } require.cache[modulePath] = null; }
setInterval(function () { var code = require('./code.js'); cleanCache(require.resolve('./code.js')); }, 10);
再执行一下,这次好多了,内存只会有轻微的增长,说明老模块占用的资源已经正确的释放掉了。 (编辑:PHP编程网 - 湛江站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|