V8中垃圾回收工作的老司机之垃圾回收实现
2023-09-15 20:16:58
V8垃圾回收工作的老司机
在上篇中我们了解了V8垃圾回收工作的背景、设计目标、整体架构以及新生代收集算法的scavenge
,在这里我们将详细介绍V8垃圾回收工作的老司机 ——老生代算法mark-sweep
& mark-compact
,以及新生代晋升老生代的机制,最后还会告诉你如何查看并扩充V8的内存。
一、老生代垃圾回收算法
因为新生代的对象生命周期较短,所以可以使用新生代垃圾回收算法scavenge
。
但由于老生代中的对象的存活时间比新生代的对象要长,很多对象会存活于多个垃圾回收周期,因此老生代使用了其他策略,包括mark-sweep
和 mark-compact
两种算法。
-
mark-sweep
算法
通过对内存中的所有对象进行标记,然后清理掉所有未标记的对象。 -
mark-compact
算法
除了标记和清理之外,mark-compact
还会对内存中的对象进行整理。在mark-compact
完成后,所有未被清理的对象都会被整理到内存空间的一块连续区域中,从而避免内存碎片。
由于mark-sweep
算法和 mark-compact
算法的实现复杂,且相关代码也比较多,因此本文不对其具体的实现进行剖析。
如果大家对具体的实现细节感兴趣,可以参考 V8 的官方文档。
二、新生代晋升老生代
新生代的晋升老生代机制,是指在scavenge
之后,将新生代的幸存对象晋升到老生代,因为这些对象已经经过了新生代垃圾回收算法的考验,因此它们在老生代中存活下来的可能性会比较大。
三、如何查看并扩充 V8 内存
- 查看 V8 内存:
通过在 JavaScript 代码中使用 process.memoryUsage()
方法可以查看 V8 内存的使用情况。
const memoryUsage = process.memoryUsage();
console.log(memoryUsage);
输出结果:
{
rss: 24716800,
heapTotal: 1759232,
heapUsed: 1154656,
external: 142352
}
rss
: 总内存使用量,包括 JavaScript 堆内存和 V8 内核内存。heapTotal
: 堆内存总量。heapUsed
: 堆内存已使用量。external
: 外部内存的使用量,包括 C++ 对象和 Node.js 模块。
- 扩充 V8 内存:
可以通过在启动 Node.js 时使用 --max-old-space-size
和 --max-new-space-size
参数来扩充 V8 内存。
例如,以下命令将把老生代的最大内存设置为 4GB,新生代的最大内存设置为 1GB:
node --max-old-space-size=4096 --max-new-space-size=1024 app.js
以上内容仅为抛砖引玉,关于 scavenge
、mark-sweep
、mark-compact
、晋升老生代的垃圾回收过程的详细、如何查看并扩充 V8 内存等相关内容的进一步学习和理解,可以参考V8的官方文档。
希望能对你有所帮助,如果有什么问题,欢迎随时提出。