Skip to content

shaw1121/node-demo

Repository files navigation

node demo

V8的垃圾回收机制

Node是一个构建在Chrome的JavaScript运行时上的平台。V8是Node的JavaScript脚本引擎。

在V8中,所有的JavaScript对象都是通过堆来进行分配的。当我们在代码中声明变量并赋值时,所使用对象的内存就分配在堆中,如果 已申请的堆空闲内存不够分配新的对象,将继续申请堆内存,直到堆的内存超过V8的限制为止。而V8会限制堆的大小,深层原因是V8的垃圾 回收机制的限制。垃圾回收是导致性能下降的主要原因。限制可以通过命令去打开,缺点是一旦生效便不能再动态改变。 node --max-old-space-size=1700 test.js // 单位为MB 针对老生代 或者 node --max-new-space-size=1024 test.js // 单位为KB 针对新生代

V8的主要垃圾回收算法

基于分代式垃圾回收机制。V8中将内存分为新生代和老生代。新生代中的对象为存活时间较短的对象,老生代中的对象为存活时间较长或常驻内存的对象。 默认情况下,V8堆内存的最大值在64位系统上约为1.4GB,在32位系统下只能使用约0.7GB内存。

  • Scavenge算法 新生代的对象主要通过该算法进行垃圾回收。在Scavenge算法的具体实现上,主要采用了Cheney算法。 它是一种采用复制的方式实现的垃圾回收算法。它将堆内存一分为二,每一部分空间称为semispace。这两个semispace空间中,只有一个处于使用中(From空间), 另一个处于闲置状态(To空间)。当我们分配对象时,先是在From空间中进行分配。当开始进行垃圾回收时,会首先检查From空间中的存活对象,这些存活对象将被 复制到To空间中,而非存活对象所占用的空间将被释放。完成复制后,From空间和To空间的角色发生对换。简言之,在垃圾回收的过程中,就是通过将存活对象在两个 semispace空间之间进行复制。

缺点: 只能使用堆内存空间的一半

优点: 由于只复制存活的对象,并且对于生命周期短的场景存活对象只占少部分,所有该算法在时间效率上表现优异。适合新生代对象生命周期短的特点。

晋升 当一个对象多次复制依然存活时,它将会被认为是生命周期较长的对象,这种对象会被移动到老生代中,采用新的算法进行管理。

晋升的条件:

  1. 一个对象是否经历过Scavenge回收
  2. To空间的内存占用比超过限制(一般为25%),

设置占用比的原因是当这次Scavenge回收完成后,这个To空间将变为From空间,接下来的内存分配将在这个空间中进行,如果占比过高,会影响后续内存分配。

  • Mark-Sweep(标记清除) & Mark-Compact(标记整理)

两者结合的方式进行垃圾回收。

M-S在标记阶段会遍历堆中的所有对象,并标记活着的对象,在随后的清除中,只清除没有被标记的对象。M-S只清理死亡对象,而Scavenge只复制或者的对象。 活对象在新生代中占比较小,死对象在老生代中占比较小,这是两种回收方式能高效工作的原因。

M-S的最大问题是在标记清除回收后,内存空间出现不连续的状态,这种内存碎片会对后续内存分配造成影响。如果需要分配一个大对象的情况,所有的碎片空间均无法完成此次分配,就会提前触发垃圾回收,而这次回收时不必要的。为解决此问题,Mark-Compact被提出。

M-C由M-S演变而来,差别在于对象在标记为死亡后,在整理的过程中,将或者的对象往一端移动,移动完成后,直接清理掉边界外的内存。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published