连接字符串的节点内存使用情况

2024-01-26

我有以下代码来测试节点虚拟机的内存使用情况:

setInterval(()=>console.log(process.memoryUsage()),1000);

( ()=> {

    const MAXTIMES = 10000000;

    let a = ( ()=> {
        let res = "";
        for(let i=0; i<MAXTIMES; i++){
            res = res + "X";
        }
        return res;
    })();


})();

//Uncomment this to give enough time for GC and check top command. 
//Not needed with setInterval in the beginning
//setTimeout(()=>{}, 10000);

top命令显示 vm 使用 ~420M 内存。

当我将 i 的最大值更改为 100000000(100M) 时,我预计内存使用量约为 620M(420M +2 字节 * 100M),但它达到了惊人的 3300~4000M。这里发生了什么? GC 是否没有拾取循环中的临时字符串?

我尝试使用var确保 i 被提升,但结果是一样的。

EDIT1:将代码更新为带注释的完整代码

EDIT2

我也在 Firefox、Safari 和 Chrome JS 控制台的随机选项卡上运行了代码,也有类似的问题。 Firefox 选项卡占用约 2.5G,Safari 选项卡占用约 6G 内存,Chrome 选项卡占用约 3G。在所有情况下,直到我关闭选项卡之前,GC 都不会声明内存。


不同的 JavaScript 引擎使用的垃圾收集策略略有不同。 Node.js 使用v8 https://developers.google.com/v8/这是最初为 Chrome 构建的引擎,并且 Chrome 仍在使用。

为了更多地了解 V8 中垃圾收集的工作原理,我推荐这篇文章,虽然很旧,但今天仍然相关:https://strongloop.com/strongblog/node-js-performance-garbage-collection/ https://strongloop.com/strongblog/node-js-performance-garbage-collection/

您可以使用以下命令查看运行节点的垃圾收集器正在做什么--trace-gc --log-gc选项。

在您的代码中,内存增加比您预期的要多得多,因为:

每次你这样做res += "X"它创建一个全新的字符串并分配 它到res然后前一个就有资格进行垃圾收集

正如@jfriend00 在评论中所写。真正可能发生的事情比这更复杂一些,但我认为我们不需要讨论细节。

我更愿意向您展示,我们在运行您的代码时可以观察到什么。

我稍微改变了一下:

const humanize = require('humanize')
setInterval(() => console.log(humanize.filesize(process.memoryUsage().heapUsed)),1000);

setInterval(() => {
    const MAXTIMES = 10000000;

    let a = ( ()=> {
        let res = "";
        console.log('starting');
        for(let i=0; i<MAXTIMES; i++){
            // Add this for last run
            // if (i % (MAXTIMES / 10) === 0) {
            //   console.log(i);
            // }
            res = res + "X";
        }
        console.log('done');
        return res;
    })();
}, 5000);

差异是: 1)humanize有助于格式化内存值。 2)我只是打印heapUsed。 3)我调用每 5 秒连接字符串的函数setInterval.

当我运行它时,我得到:

$ node index.js
4.36 MB
4.39 MB
4.40 MB
4.40 MB
starting
done
385.80 MB
385.80 MB
385.80 MB
385.80 MB
385.80 MB
starting
done
385.52 MB
4.00 MB
4.00 MB
4.00 MB
4.01 MB
starting
done
385.63 MB
385.63 MB
385.64 MB
385.64 MB
385.64 MB
starting
done
385.77 MB
385.77 MB
385.77 MB
385.78 MB
385.78 MB
starting
done
385.54 MB
...

因此,在调用该函数之前,内存只有 4Mb。 “starting”和“done”总是一个接一个地打印,因为它们是同步的。 第一次通话后heapUsed到达385.80Mb.

5 秒后,再次调用该函数时,内存将变为385.52 MB。请注意,内存不会加倍。相反,您可以看到在第二次运行中内存达到4.00 MB2秒后。之后,当再次调用该函数时,内存会再次循环385Mb.

--max-old-space-size限制节点可以使用的最大内存。 如果我再次运行该程序,将内存限制为 400MB,则输出会有所不同:

$ node --max-old-space-size=400 index.js
4.36 MB
4.39 MB
4.40 MB
4.40 MB
starting
done
385.52 MB
384.04 MB
4.00 MB
4.00 MB
4.00 MB
starting
done
385.48 MB
4.00 MB
4.00 MB
4.00 MB
4.01 MB
starting
done
386.11 MB
384.21 MB
4.00 MB
4.00 MB
4.00 MB
starting
done
385.56 MB
4.00 MB

可以看到,函数调用后,内存立即就到了385Mb但它很快就会4.00 MB.

这是因为对内存的限制使得垃圾收集算法在回收内存时更加“激进”,以防止内存不足错误。

要了解 V8 到底在做什么,我们可以使用--trace-gc --log-gc参数。我还添加了if (i % (MAXTIMES / 10) === 0) console.log(i);循环中以确保事情发生时清晰可见。

$ node --trace-gc --log-gc --max-old-space-size=400  index.js
[10826:0x103000000]       51 ms: Scavenge 3.4 (6.4) -> 3.2 (7.4) MB, 1.3 / 0.0 ms  allocation failure
[10826:0x103000000]       61 ms: Scavenge 3.5 (7.4) -> 3.5 (8.4) MB, 1.1 / 0.0 ms  allocation failure
4.64 MB
4.67 MB
4.68 MB
4.68 MB
starting
0
[10826:0x103000000]     5094 ms: Scavenge 4.8 (8.9) -> 4.6 (8.9) MB, 1.1 / 0.0 ms  allocation failure
[10826:0x103000000]     5106 ms: Scavenge 5.5 (8.9) -> 5.5 (9.4) MB, 2.8 / 0.0 ms  allocation failure
[10826:0x103000000]     5109 ms: Scavenge 6.1 (9.4) -> 6.1 (10.4) MB, 2.7 / 0.0 ms  allocation failure
[10826:0x103000000]     5112 ms: Scavenge 7.0 (10.4) -> 7.0 (12.4) MB, 2.4 / 0.0 ms  allocation failure
[10826:0x103000000]     5115 ms: Scavenge 7.5 (12.4) -> 7.5 (16.4) MB, 2.4 / 0.0 ms  allocation failure
[10826:0x103000000]     5122 ms: Scavenge 9.9 (16.4) -> 10.0 (16.9) MB, 4.8 / 0.0 ms  allocation failure
[10826:0x103000000]     5127 ms: Scavenge 10.4 (16.9) -> 10.3 (25.4) MB, 5.5 / 0.0 ms  allocation failure
[10826:0x103000000]     5141 ms: Scavenge 15.8 (25.4) -> 16.0 (25.9) MB, 10.4 / 0.0 ms  allocation failure
[10826:0x103000000]     5154 ms: Scavenge 16.2 (25.9) -> 16.0 (43.4) MB, 12.9 / 0.0 ms  allocation failure
[10826:0x103000000]     5182 ms: Scavenge 27.6 (43.4) -> 28.1 (43.9) MB, 21.2 / 0.0 ms  allocation failure
[10826:0x103000000]     5202 ms: Scavenge 28.1 (43.9) -> 27.6 (63.4) MB, 20.2 / 0.0 ms  allocation failure
1000000
[10826:0x103000000]     5234 ms: Scavenge 43.3 (63.4) -> 44.0 (63.9) MB, 24.7 / 0.0 ms  allocation failure
[10826:0x103000000]     5266 ms: Scavenge 44.1 (63.9) -> 43.3 (79.4) MB, 32.4 / 0.0 ms  allocation failure
[10826:0x103000000]     5293 ms: Scavenge 59.1 (79.4) -> 59.8 (79.9) MB, 22.3 / 0.0 ms  allocation failure
[10826:0x103000000]     5323 ms: Scavenge 59.8 (79.9) -> 59.1 (95.4) MB, 30.0 / 0.0 ms  allocation failure
[10826:0x103000000]     5375 ms: Scavenge 74.8 (95.4) -> 75.5 (95.9) MB, 19.9 / 0.0 ms  allocation failure
[10826:0x103000000]     5407 ms: Scavenge 75.5 (95.9) -> 74.8 (111.4) MB, 30.5 / 0.0 ms  allocation failure
2000000
[10826:0x103000000]     5444 ms: Mark-sweep 82.2 (111.4) -> 82.0 (111.4) MB, 8.6 / 0.0 ms  (+ 54.6 ms in 371 steps since start of marking, biggest step 4.0 ms, walltime since start of marking 177 ms) finalize incremental marking via stack guard GC in old space requested
[10826:0x103000000]     5478 ms: Scavenge 90.3 (111.4) -> 90.7 (118.9) MB, 31.9 / 0.0 ms  allocation failure
[10826:0x103000000]     5505 ms: Scavenge 97.7 (118.9) -> 97.7 (127.4) MB, 25.2 / 0.0 ms  allocation failure
[10826:0x103000000]     5534 ms: Scavenge 106.0 (127.4) -> 106.1 (134.9) MB, 26.6 / 0.0 ms  allocation failure
[10826:0x103000000]     5562 ms: Scavenge 113.1 (134.9) -> 113.0 (143.4) MB, 25.7 / 0.0 ms  allocation failure
3000000
[10826:0x103000000]     5589 ms: Scavenge 121.4 (143.4) -> 121.5 (149.4) MB, 23.8 / 0.0 ms  allocation failure
[10826:0x103000000]     5626 ms: Scavenge 128.4 (149.4) -> 128.4 (158.4) MB, 35.4 / 0.0 ms  allocation failure
[10826:0x103000000]     5656 ms: Scavenge 136.8 (158.4) -> 136.9 (165.4) MB, 27.3 / 0.0 ms  allocation failure
[10826:0x103000000]     5699 ms: Scavenge 143.8 (165.4) -> 143.7 (173.9) MB, 26.4 / 0.0 ms  allocation failure
[10826:0x103000000]     5762 ms: Scavenge 152.3 (173.9) -> 152.3 (180.9) MB, 25.3 / 0.0 ms  allocation failure
4000000
[10826:0x103000000]     5829 ms: Scavenge 159.1 (180.9) -> 159.0 (189.4) MB, 26.8 / 0.0 ms  allocation failure
[10826:0x103000000]     5854 ms: Mark-sweep 161.0 (189.4) -> 160.7 (196.9) MB, 3.6 / 0.0 ms  (+ 108.5 ms in 387 steps since start of marking, biggest step 4.4 ms, walltime since start of marking 228 ms) finalize incremental marking via stack guard GC in old space requested
[10826:0x103000000]     5891 ms: Scavenge 174.4 (196.9) -> 175.1 (198.9) MB, 32.0 / 0.0 ms  allocation failure
[10826:0x103000000]     5923 ms: Scavenge 176.4 (198.9) -> 175.8 (212.9) MB, 31.6 / 0.0 ms  allocation failure
[10826:0x103000000]     5946 ms: Scavenge 190.1 (212.9) -> 190.8 (214.4) MB, 18.6 / 0.0 ms  allocation failure
[10826:0x103000000]     5976 ms: Scavenge 191.5 (214.4) -> 190.8 (229.4) MB, 29.8 / 0.0 ms  allocation failure
5000000
[10826:0x103000000]     6002 ms: Scavenge 205.8 (229.4) -> 206.5 (229.4) MB, 19.4 / 0.0 ms  allocation failure
[10826:0x103000000]     6034 ms: Scavenge 206.5 (229.4) -> 205.8 (244.4) MB, 31.7 / 0.0 ms  allocation failure
[10826:0x103000000]     6059 ms: Scavenge 221.5 (244.4) -> 222.2 (244.9) MB, 20.9 / 0.0 ms  allocation failure
[10826:0x103000000]     6088 ms: Scavenge 222.3 (244.9) -> 221.5 (260.4) MB, 28.4 / 0.0 ms  allocation failure
6000000
[10826:0x103000000]     6114 ms: Scavenge 237.3 (260.4) -> 238.0 (260.9) MB, 22.3 / 0.0 ms  allocation failure
[10826:0x103000000]     6142 ms: Scavenge 238.0 (260.9) -> 237.3 (276.4) MB, 27.5 / 0.0 ms  allocation failure
[10826:0x103000000]     6169 ms: Scavenge 253.0 (276.4) -> 253.7 (276.9) MB, 22.4 / 0.0 ms  allocation failure
[10826:0x103000000]     6203 ms: Scavenge 253.7 (276.9) -> 253.0 (292.4) MB, 33.6 / 0.0 ms  allocation failure
[10826:0x103000000]     6380 ms: Scavenge 268.7 (292.4) -> 269.4 (292.9) MB, 20.6 / 0.0 ms  allocation failure
[10826:0x103000000]     6414 ms: Scavenge 269.5 (292.9) -> 268.7 (308.4) MB, 32.1 / 0.0 ms  allocation failure
[10826:0x103000000]     6446 ms: Mark-sweep 269.9 (308.4) -> 269.9 (308.4) MB, 2.1 / 0.0 ms  (+ 183.4 ms in 270 steps since start of marking, biggest step 5.5 ms, walltime since start of marking 304 ms) finalize incremental marking via stack guard GC in old space requested
7000000
[10826:0x103000000]     6478 ms: Scavenge 284.5 (308.4) -> 285.2 (309.9) MB, 25.2 / 0.0 ms  allocation failure
[10826:0x103000000]     6510 ms: Scavenge 285.6 (309.9) -> 284.9 (324.9) MB, 32.4 / 0.0 ms  allocation failure
[10826:0x103000000]     6538 ms: Scavenge 300.2 (324.9) -> 300.9 (325.9) MB, 22.8 / 0.0 ms  allocation failure
[10826:0x103000000]     6570 ms: Scavenge 300.9 (325.9) -> 300.2 (341.4) MB, 31.8 / 0.0 ms  allocation failure
8000000
[10826:0x103000000]     6595 ms: Scavenge 315.9 (341.4) -> 316.7 (342.4) MB, 20.6 / 0.0 ms  allocation failure
[10826:0x103000000]     6643 ms: Scavenge 316.7 (342.4) -> 316.0 (357.9) MB, 48.2 / 0.0 ms  allocation failure
[10826:0x103000000]     6670 ms: Scavenge 331.7 (357.9) -> 332.4 (358.9) MB, 21.9 / 0.0 ms  allocation failure
[10826:0x103000000]     6703 ms: Scavenge 332.4 (358.9) -> 331.7 (374.4) MB, 32.4 / 0.0 ms  allocation failure
[10826:0x103000000]     6728 ms: Scavenge 347.4 (374.4) -> 348.1 (375.4) MB, 20.7 / 0.0 ms  allocation failure
[10826:0x103000000]     6756 ms: Scavenge 348.1 (375.4) -> 347.4 (390.9) MB, 27.9 / 0.0 ms  allocation failure
9000000
[10826:0x103000000]     6986 ms: Mark-sweep 350.9 (390.9) -> 350.8 (390.9) MB, 2.3 / 0.0 ms  (+ 225.8 ms in 55 steps since start of marking, biggest step 6.0 ms, walltime since start of marking 230 ms) finalize incremental marking via stack guard GC in old space requested
[10826:0x103000000]     7020 ms: Scavenge 363.1 (390.9) -> 363.7 (392.4) MB, 30.2 / 0.0 ms  allocation failure
[10826:0x103000000]     7055 ms: Scavenge 366.6 (392.4) -> 366.1 (404.9) MB, 33.7 / 0.0 ms  allocation failure
[10826:0x103000000]     7080 ms: Scavenge 378.9 (404.9) -> 379.3 (407.9) MB, 21.7 / 0.0 ms  allocation failure
[10826:0x103000000]     7106 ms: Scavenge 381.7 (407.9) -> 381.2 (420.9) MB, 25.2 / 0.0 ms  allocation failure
[10826:0x103000000]     7342 ms: Mark-sweep 384.8 (420.9) -> 384.7 (422.9) MB, 3.3 / 0.0 ms  (+ 231.9 ms in 58 steps since start of marking, biggest step 5.5 ms, walltime since start of marking 237 ms) finalize incremental marking via stack guard GC in old space requested
done
385.70 MB
[10826:0x103000000]     7384 ms: Mark-sweep 385.7 (422.9) -> 4.2 (40.9) MB, 39.4 / 0.0 ms  (+ 0.0 ms in 1 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 39 ms) finalize incremental marking via task GC in old space requested
4.22 MB
4.23 MB
4.23 MB
4.23 MB
starting
0
[10826:0x103000000]    12380 ms: Scavenge 20.0 (40.9) -> 20.7 (40.9) MB, 19.4 / 0.0 ms  allocation failure
[10826:0x103000000]    12406 ms: Scavenge 20.7 (40.9) -> 20.0 (55.4) MB, 26.7 / 0.0 ms  allocation failure
[10826:0x103000000]    12430 ms: Scavenge 35.7 (55.4) -> 36.4 (55.9) MB, 19.5 / 0.0 ms  allocation failure
[10826:0x103000000]    12457 ms: Scavenge 36.4 (55.9) -> 35.7 (71.4) MB, 27.3 / 0.0 ms  allocation failure
1000000
[10826:0x103000000]    12484 ms: Scavenge 51.4 (71.4) -> 52.1 (71.9) MB, 22.6 / 0.0 ms  allocation failure
[10826:0x103000000]    12513 ms: Scavenge 52.2 (71.9) -> 51.4 (87.4) MB, 28.2 / 0.0 ms  allocation failure
[10826:0x103000000]    12551 ms: Scavenge 67.2 (87.4) -> 67.9 (87.9) MB, 21.9 / 0.0 ms  allocation failure
[10826:0x103000000]    12578 ms: Scavenge 67.9 (87.9) -> 67.2 (103.4) MB, 26.9 / 0.0 ms  allocation failure
2000000
[10826:0x103000000]    12646 ms: Mark-sweep 81.7 (103.4) -> 81.7 (103.4) MB, 30.1 / 0.0 ms  (+ 46.7 ms in 311 steps since start of marking, biggest step 5.2 ms, walltime since start of marking 189 ms) finalize incremental marking via stack guard GC in old space requested
[10826:0x103000000]    12680 ms: Scavenge 82.9 (103.4) -> 82.9 (118.4) MB, 31.8 / 0.0 ms  allocation failure
[10826:0x103000000]    12712 ms: Scavenge 97.5 (118.4) -> 98.1 (119.9) MB, 20.8 / 0.0 ms  allocation failure
[10826:0x103000000]    12738 ms: Scavenge 98.6 (119.9) -> 98.0 (134.9) MB, 26.8 / 0.0 ms  allocation failure
[10826:0x103000000]    12762 ms: Scavenge 113.1 (134.9) -> 113.8 (135.9) MB, 20.1 / 0.0 ms  allocation failure
[10826:0x103000000]    12789 ms: Scavenge 113.9 (135.9) -> 113.1 (151.4) MB, 26.8 / 0.0 ms  allocation failure
3000000
[10826:0x103000000]    12813 ms: Scavenge 128.9 (151.4) -> 129.6 (151.9) MB, 20.6 / 0.0 ms  allocation failure
[10826:0x103000000]    12839 ms: Scavenge 129.6 (151.9) -> 128.9 (166.4) MB, 25.4 / 0.0 ms  allocation failure
[10826:0x103000000]    12913 ms: Scavenge 144.6 (166.4) -> 145.3 (166.9) MB, 20.9 / 0.0 ms  allocation failure
[10826:0x103000000]    12944 ms: Scavenge 145.3 (166.9) -> 144.6 (182.4) MB, 29.2 / 0.0 ms  allocation failure
[10826:0x103000000]    12997 ms: Mark-sweep 151.5 (182.4) -> 151.5 (182.4) MB, 3.9 / 0.0 ms  (+ 98.2 ms in 363 steps since start of marking, biggest step 5.0 ms, walltime since start of marking 208 ms) finalize incremental marking via stack guard GC in old space requested
4000000
[10826:0x103000000]    13028 ms: Scavenge 160.3 (182.4) -> 160.8 (189.4) MB, 28.7 / 0.0 ms  allocation failure
[10826:0x103000000]    13054 ms: Scavenge 167.3 (189.4) -> 167.2 (198.4) MB, 24.2 / 0.0 ms  allocation failure
[10826:0x103000000]    13079 ms: Scavenge 176.1 (198.4) -> 176.2 (205.4) MB, 22.3 / 0.0 ms  allocation failure
[10826:0x103000000]    13104 ms: Scavenge 182.6 (205.4) -> 182.4 (214.9) MB, 23.8 / 0.0 ms  allocation failure
[10826:0x103000000]    13129 ms: Scavenge 191.5 (214.9) -> 191.6 (221.4) MB, 23.1 / 0.0 ms  allocation failure
5000000
[10826:0x103000000]    13155 ms: Scavenge 197.9 (221.4) -> 197.7 (230.9) MB, 24.9 / 0.0 ms  allocation failure
[10826:0x103000000]    13181 ms: Scavenge 206.9 (230.9) -> 207.1 (237.4) MB, 24.0 / 0.0 ms  allocation failure
[10826:0x103000000]    13206 ms: Scavenge 213.2 (237.4) -> 213.0 (246.9) MB, 23.2 / 0.0 ms  allocation failure
[10826:0x103000000]    13232 ms: Scavenge 222.4 (246.9) -> 222.5 (253.4) MB, 23.0 / 0.0 ms  allocation failure
[10826:0x103000000]    13258 ms: Scavenge 228.5 (253.4) -> 228.3 (262.9) MB, 24.9 / 0.0 ms  allocation failure
6000000
[10826:0x103000000]    13316 ms: Scavenge 237.8 (262.9) -> 238.0 (267.9) MB, 24.6 / 0.0 ms  allocation failure
[10826:0x103000000]    13381 ms: Scavenge 243.8 (267.9) -> 243.6 (277.9) MB, 25.9 / 0.0 ms  allocation failure
[10826:0x103000000]    13480 ms: Mark-sweep 251.5 (277.9) -> 251.2 (282.9) MB, 5.3 / 0.0 ms  (+ 159.5 ms in 371 steps since start of marking, biggest step 4.1 ms, walltime since start of marking 248 ms) finalize incremental marking via stack guard GC in old space requested
[10826:0x103000000]    13517 ms: Scavenge 259.1 (282.9) -> 259.4 (290.4) MB, 34.7 / 0.0 ms  allocation failure
[10826:0x103000000]    13545 ms: Scavenge 266.9 (290.4) -> 266.9 (298.4) MB, 23.6 / 0.0 ms  allocation failure
7000000
[10826:0x103000000]    13571 ms: Scavenge 274.8 (298.4) -> 274.8 (306.4) MB, 24.2 / 0.0 ms  allocation failure
[10826:0x103000000]    13597 ms: Scavenge 282.3 (306.4) -> 282.3 (313.9) MB, 24.2 / 0.0 ms  allocation failure
[10826:0x103000000]    13636 ms: Scavenge 290.1 (313.9) -> 290.1 (321.9) MB, 36.8 / 0.0 ms  allocation failure
[10826:0x103000000]    13662 ms: Scavenge 297.7 (321.9) -> 297.7 (329.9) MB, 24.3 / 0.0 ms  allocation failure
[10826:0x103000000]    13687 ms: Scavenge 305.5 (329.9) -> 305.5 (337.4) MB, 23.7 / 0.0 ms  allocation failure
8000000
[10826:0x103000000]    13717 ms: Scavenge 313.0 (337.4) -> 313.0 (345.4) MB, 27.6 / 0.0 ms  allocation failure
[10826:0x103000000]    13746 ms: Scavenge 320.9 (345.4) -> 320.9 (352.9) MB, 25.9 / 0.0 ms  allocation failure
[10826:0x103000000]    13773 ms: Scavenge 328.4 (352.9) -> 328.4 (360.9) MB, 24.9 / 0.0 ms  allocation failure
[10826:0x103000000]    13798 ms: Scavenge 336.2 (360.9) -> 336.2 (368.9) MB, 23.5 / 0.0 ms  allocation failure
[10826:0x103000000]    14033 ms: Mark-sweep 339.4 (368.9) -> 339.0 (376.9) MB, 4.0 / 0.0 ms  (+ 229.2 ms in 50 steps since start of marking, biggest step 5.7 ms, walltime since start of marking 234 ms) finalize incremental marking via stack guard GC in old space requested
9000000
[10826:0x103000000]    14072 ms: Scavenge 351.6 (376.9) -> 352.2 (379.9) MB, 35.7 / 0.0 ms  allocation failure
[10826:0x103000000]    14101 ms: Scavenge 354.7 (379.9) -> 354.3 (392.9) MB, 28.0 / 0.0 ms  allocation failure
[10826:0x103000000]    14125 ms: Scavenge 367.3 (392.9) -> 367.8 (395.9) MB, 21.4 / 0.0 ms  allocation failure
[10826:0x103000000]    14154 ms: Scavenge 369.9 (395.9) -> 369.3 (409.4) MB, 28.1 / 0.0 ms  allocation failure
[10826:0x103000000]    14178 ms: Scavenge 383.0 (409.4) -> 383.5 (411.9) MB, 20.5 / 0.0 ms  allocation failure
[10826:0x103000000]    14311 ms: Scavenge 385.0 (411.9) -> 384.4 (425.4) MB, 30.4 / 0.0 ms  allocation failure
done
385.77 MB
[10826:0x103000000]    14455 ms: Mark-sweep 385.8 (425.4) -> 382.9 (425.4) MB, 1.2 / 0.0 ms  (+ 244.2 ms in 103 steps since start of marking, biggest step 6.2 ms, walltime since start of marking 278 ms) finalize incremental marking via task GC in old space requested
382.93 MB
[10826:0x103000000]    15413 ms: Mark-sweep 382.9 (425.4) -> 4.2 (41.9) MB, 0.8 / 0.0 ms  (+ 2.8 ms in 4 steps since start of marking, biggest step 1.1 ms, walltime since start of marking 4 ms) finalize incremental marking via task GC in old space requested
4.22 MB
4.23 MB

在这种情况下,清除周期并不会真正回收任何内存,我们必须等待完整的标记清除完成才能释放所有内存。

有道理吗?

最后,我想补充一点:

  1. 真实代码通常不会在一次时间内进行 1000 万次字符串连接。
  2. V8 的垃圾收集算法通常会做正确的事情,以便在防止进程耗尽内存和防止自身不必要地减慢进程之间取得适当的平衡。
  3. 如果您遇到垃圾收集问题,您需要进行一些分析,解决方案通常意味着重构代码以一次性完成更少的工作。它可能要复杂得多,但深入探讨可能与这个问题无关。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

连接字符串的节点内存使用情况 的相关文章

随机推荐