加入收藏 | 设为首页 | 会员中心 | 我要投稿 网站开发网_安阳站长网 (https://www.0372zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

Node.js Web应用代码热更新的另类思路

发布时间:2016-04-20 19:15:09 所属栏目:编程 来源:百度Fex
导读:本文则提供了另外一种思路,只需要很小的改造,就可以实现真正的0重启热更新代码,解决 Node.js 开发 Web 应用时恼人的代码更新问题。

那么我们的课题就是,如何让老模块的代码更新后,确保没有对象保持了模块的引用。首先我们以 如何更新模块代码 一节中的代码为例,看看老模块资源不回收会出现什么问题。为了让结果更显著,我们修改一下 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);

再执行一下,这次好多了,内存只会有轻微的增长,说明老模块占用的资源已经正确的释放掉了。

(编辑:网站开发网_安阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!