当前位置: 首页 > 后端技术 > Node.js

node.js简单学习笔记——节点内存管理与GC机制

时间:2023-04-03 18:16:54 Node.js

在node.js中,内存主要分为两部分,堆内存和栈内存。堆内存(heap):存储对象和闭包上下文,v8使用垃圾回收机制管理堆内存和栈内存(stack):存储局部变量,栈内存的分配比较简单。当程序离开某个作用域时,它的栈指针向下移动(回滚),整个作用域的局部变量就会被弹出栈,被回收。可以通过process.memoryUsage()查看内存使用情况,单位为bytemanagedbyv8分配给javascript的c++对象的内存通常由v8分配为64位系统1.4GB,32位系统0.7GB。Node将堆内存分为新生代和老年代。Oldgenerationofshortobjects:在分代的基础上,存放存活时间长的对象。对于新一代,使用Scavenge算法。老年代使用Mark-Sweep和Mark-Compact对象,这些对象已经进行了复制翻转操作。To空间使用率超过25%。之所以设置25%的比例,是因为To空间会变成From空间。如果使用率过高,可能会影响后续的内存分配。Scavenge算法Scavenge算法主要由Cheney算法实现。Cheney算法将新生代分为两部分,称为SemiSpace空间,这两个SemiSpace空间称为From空间和To空间。From空间是已用空间,To空间是闲置空间。分配新的内存空间时,会分配到From空间。当垃圾回收开始时,会检查From空间中的对象,将存活的对象复制到To空间,释放From空间,将From空间和To空间颠倒过来。Scavenge算法的优点是速度快,没??有内存碎片。缺点是只能使用一般的内存空间。但是由于新生代都是存活时间短的对象,所以需要复制的对象很少。是典型的以空间换时间的算法。仅适用于新生代垃圾回收策略。在新生代回收阶段,如果存活的对象满足以下两个条件,该对象将被移动到老年代。这个阶段称为被提升的对象经历了复制翻转操作。To空间使用率超过25%。之所以设置25%的比例,是因为To空间会变成From空间。如果使用率过高,可能会影响后续的内存分配。Mark-Sweep(标记清除)和Mark-Compact(标记整理)Mark-Sweep分为标记和清除两个阶段。在标记阶段,遍历所有老年代对象,标记存活下来的对象。在清理阶段,释放未使用的对象。标记记忆。Mark-Sweep最大的问题是在清除阶段之后,内存空间会出现不连续,影响以后的内存分配。可能有一个对象需要分配较大的内存空间,但是现有的内存碎片无法完成分配,进行早期垃圾回收,这是没有必要的。为了解决Mark-Sweep的内存碎片问题,提出了Mark-Compact。主要是将存活的对象在标记后移动到一侧,移动完成后直接释放边界外的内存。IncrementalMarking的三种算法在执行时,为了保证javascript应用逻辑与垃圾回收机制一致,需要在垃圾回收时停止应用逻辑。这种情况被称为“全停顿”的新一代Scavange算法。更小、更少的幸存对象,更小的完全暂停的影响。但是老年代内存空间更大,存储对象更多,全停时间更长。因此,为了减少停顿空间,V8从标记阶段开始,改为增量标记(IncrementalMarking)。把整体拆分成一个个小“步”,让js应用逻辑执行一段时间,不执行一个“步”,垃圾回收和应用逻辑交替进行。