我编写了一个非常简单的脚本来查询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来做它的事情,并确保您不保留对不再使用的大数据结构的引用永久变量(在持久作用域中声明的变量,例如顶级变量)中需要的值,或者累积不再需要的数据(如数组)的数据。
FYI,清除对大数据结构的引用并不会从内存中删除它-只是使它在GC决定运行时才有资格使用GC(如果没有其他变量指向相同的数据)。