直观感受一下GC

1,046 阅读2分钟

Node的GC直观体验

目的:我们都知道js是自动GC的,但是从来没看见过它的GC,没有一个直观感受,我通过一个node的代码带你感受一下node的GC过程。

Node GC demo

let count = 0;
const format = function (bytes) {
    return (bytes / 1024 / 1024).toFixed(2) + ' MB';
};
const print = function() {
    const memoryUsage = process.memoryUsage();

    console.log(count, JSON.stringify({
        rss: format(memoryUsage.rss),
        heapTotal: format(memoryUsage.heapTotal),
        heapUsed: format(memoryUsage.heapUsed),
        external: format(memoryUsage.external),
    }));
}
function Quantity(num) {
    if (num) {
        return new Array(num * 1024 * 1024);
    }

    return num;
}

function Fruit(name, quantity) {
    this.name = name
    this.quantity = new Quantity(quantity)
}

let apple = new Fruit('apple');
print();
let banana = new Fruit('banana', 20);
print();
banana = null;
print();
setInterval(() => {
    count ++;
    print();
}, 1000);

打印信息:

0 {"rss":"21.78 MB","heapTotal":"4.05 MB","heapUsed":"2.05 MB","external":"0.65 MB"}
0 {"rss":"182.66 MB","heapTotal":"164.44 MB","heapUsed":"162.52 MB","external":"0.80 MB"}
0 {"rss":"182.67 MB","heapTotal":"164.44 MB","heapUsed":"162.52 MB","external":"0.80 MB"}
1 {"rss":"182.75 MB","heapTotal":"164.69 MB","heapUsed":"162.55 MB","external":"0.80 MB"}
2 {"rss":"182.75 MB","heapTotal":"164.69 MB","heapUsed":"162.56 MB","external":"0.80 MB"}
3 {"rss":"182.79 MB","heapTotal":"164.69 MB","heapUsed":"162.56 MB","external":"0.80 MB"}
4 {"rss":"182.80 MB","heapTotal":"164.69 MB","heapUsed":"162.57 MB","external":"0.80 MB"}
5 {"rss":"182.80 MB","heapTotal":"164.69 MB","heapUsed":"162.57 MB","external":"0.80 MB"}
6 {"rss":"182.80 MB","heapTotal":"164.69 MB","heapUsed":"162.58 MB","external":"0.80 MB"}
7 {"rss":"182.82 MB","heapTotal":"164.69 MB","heapUsed":"162.58 MB","external":"0.80 MB"}
8 {"rss":"182.83 MB","heapTotal":"164.69 MB","heapUsed":"162.59 MB","external":"0.80 MB"}
9 {"rss":"21.49 MB","heapTotal":"3.93 MB","heapUsed":"1.83 MB","external":"0.79 MB"}
10 {"rss":"21.50 MB","heapTotal":"3.93 MB","heapUsed":"1.84 MB","external":"0.79 MB"}
11 {"rss":"21.50 MB","heapTotal":"3.93 MB","heapUsed":"1.84 MB","external":"0.79 MB"}

我们都知道,当一个引用被指定为null时候就是这个对象可以被回收了,上面代码我们指定了banana为null,所以在GC的时候会被垃圾回收。你会发现在第八次到第九次时候发生了GC,所以heap堆上的内存减小了。

感受一下手动GC

执行:node --expose-gc memory.js

......
let apple = new Fruit('apple');
print();
let banana = new Fruit('banana', 20);
print();
banana = null;
print();
global.gc();

setInterval(() => {
    count ++;
    print();
}, 1000);

手动执行GC后输出如下:

0 {"rss":"22.29 MB","heapTotal":"4.18 MB","heapUsed":"2.14 MB","external":"0.65 MB"}
0 {"rss":"183.00 MB","heapTotal":"164.44 MB","heapUsed":"162.47 MB","external":"0.80 MB"}
0 {"rss":"183.01 MB","heapTotal":"164.44 MB","heapUsed":"162.47 MB","external":"0.80 MB"}
1 {"rss":"23.25 MB","heapTotal":"4.68 MB","heapUsed":"1.84 MB","external":"0.79 MB"}
2 {"rss":"23.25 MB","heapTotal":"4.68 MB","heapUsed":"1.86 MB","external":"0.79 MB"}
3 {"rss":"23.25 MB","heapTotal":"4.68 MB","heapUsed":"1.86 MB","external":"0.79 MB"}
4 {"rss":"23.25 MB","heapTotal":"4.68 MB","heapUsed":"1.86 MB","external":"0.79 MB"}
5 {"rss":"23.25 MB","heapTotal":"4.68 MB","heapUsed":"1.87 MB","external":"0.79 MB"}
6 {"rss":"23.25 MB","heapTotal":"4.68 MB","heapUsed":"1.87 MB","external":"0.79 MB"}

你会发现手动GC后banana对象立马释放了,内存减小。

参考

值得推荐的gitbook: www.nodejs.red/#/nodejs/me…