【发布时间】:2020-01-02 14:41:25
【问题描述】:
我写了一个非常简单的脚本来查询redis中列表的长度并输出内存使用情况。
随着时间的推移,“堆使用”内存似乎越来越高。
这是否推断出内存泄漏,以及如何更改此代码以防止这种情况发生?
输出:
[2020-01-02 16:59:09] Queue length > 0
[2020-01-02 16:59:09] Test queue length is 121
[2020-01-02 16:59:09] Heap total: 18.23MB, Heap Used: 8.43MB
[2020-01-02 16:59:11] Queue length > 0
[2020-01-02 16:59:11] Test queue length is 121
[2020-01-02 16:59:11] Heap total: 18.73MB, Heap Used: 8.70MB
[2020-01-02 16:59:13] Queue length > 0
[2020-01-02 16:59:13] Test queue length is 121
[2020-01-02 16:59:13] Heap total: 18.73MB, Heap Used: 8.72MB
...
[2020-01-02 17:03:53] Queue length > 0
[2020-01-02 17:03:53] Test queue length is 121
[2020-01-02 17:03:53] Heap total: 18.73MB, Heap Used: 11.17MB
代码:
const Redis = require('ioredis');
const redis = new Redis();
const dateformat = require('dateformat');
const log = console.log;
console.log = function () {
let output = ['[',dateformat(new Date(), "yyyy-mm-dd HH:MM:ss")];
output.push(']');
output = [output.join('')]
output = output.concat([].slice.call(arguments));
log.apply(console,
output
);
}
function loop() {
redis.llen('test').then( (queue_length) => {
if (queue_length > 0) {
console.log("Queue length > 0")
}
console.log(`Test queue length is ${queue_length}`)
let m = process.memoryUsage()
console.log(`Heap total: ${(m['heapTotal']/1024/1024).toFixed(2)}MB, Heap Used: ${(m['heapUsed']/1024/1024).toFixed(2)}MB`);
})
}
setInterval(loop, 2000)
编辑:
最终我看到我只能假设是垃圾收集:
[2020-01-02 17:05:41] Queue length > 0
[2020-01-02 17:05:41] CDR queue length is 121
[2020-01-02 17:05:41] Heap total: 13.73MB, Heap User: 8.63MB
我不确定随着内存继续上升,是否仍然推断出泄漏,然后在垃圾回收后下降。最佳做法是在 setInterval 循环期间清除变量分配,还是将其留给 GC?
【问题讨论】:
-
有一些手动清除指向非常大数据结构的变量的用例,但大多数情况下,在 Javascript 中,您只需让 GC 完成它的工作,并确保您不保留对大数据结构的引用永久变量中不再需要的数据结构(在顶级范围内声明的变量)或在数组等结构中累积不再需要的数据。仅供参考,清除对大型数据结构的引用并不会在那时将其从内存中删除 - 它只是在 GC 决定运行时使其符合 GC 条件。
-
谢谢@jfriend00,你已经非常简单地回答了我的另一个问题!我相信这个评论简洁地回答了这个问题,如果你想把它作为答案发布,我会这样标记它。谢谢!
标签: javascript node.js memory-management