垃圾回收机制
调用栈垃圾回收机制
调用栈有个指向栈顶的指针ESP,当栈顶执行上下文执行完成时,指针ESP向下移动一位,这时候已执行完成的上下文就被置空了,当在有执行上下文入栈,则直接覆盖此执行上下文,实现回收。
堆内存回收机制
代际假说
代际假说有以下两个特点: 第一个是大部分对象在内存中存在的时间很短,简单来说,就是很多对象一经分配内存,很快就变得不可访问; 第二个是不死的对象,会活得更久。
新生代 老生代
新生代中存放的是生存时间短的对象,老生代中存放的生存时间久的对象。
新生区通常只支持 1~8M 的容量,而老生区支持的容量就大很多了。对于这两块区域,V8 分别使用两个不同的垃圾回收器,以便更高效地实施垃圾回收。
标记清除:标记活动对象与非活动对象,标记完成进行清除(什么时候触发开始标记呢????)
副回收器 主回收器
副回收器处理新生代区域,主回收器处理老生代区域
副回收器(Scavenge算法):将新生代划分为对象区域,空闲区域两个区域。
新加入的对象都会存放到对象区域,当对象区域快被写满时,就需要执行一次垃圾清理操作。对活动对象与非活动对象进行对应标记,标记完成时处理非活动对象进行回收。回收时并对存活的活动对象进行整理(将活动对象有序的排列起来复制到空闲区域)当完成整理的时候,将对象区域和空闲区域进行互换,即原空闲区域为现对象区域,原对象区域为现空闲区域。
注意:由于算法特性,需要操作对象复制和区域互换,考虑效率性能问题,所以新生代设计成容量较小。由于新生代空间较小,容易占满,所以对象有个晋升策略,也就是经过两次垃圾回收依然还存活的对象,会被移动到老生代中。
主垃圾回收器是采用标记 - 清除(Mark-Sweep)的算法进行垃圾回收(遍历调用栈标记对象是否是活动对象非活动对象)
对一块内存多次执行标记 - 清除算法后,会产生大量不连续的内存碎片。而碎片过多会导致大对象无法分配到足够的连续内存,于是又产生了另外一种算法——标记 - 整理(Mark-Compact)这个标记过程仍然与标记 - 清除算法里的是一样的,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。