垃圾回收系统,不仅需要收回释放的对象,还要控制内存碎片化。
标记清扫:第一追踪阶段,第二清扫阶段。深度优先遍历全部两遍,效率低下。
效率解决方案:把清扫工作交个分配器,但是会造成内存碎片。
内存碎片解决方案:用一个数字来取模,让回收延迟几个周期。(因为局部性,几 个周期后会成批死亡,虽然会内存泄露)
标记整理:标记阶段、整理阶段。整体过程中,会多次遍历堆。
解决方案:优先使用标记清楚,碎片率到达一定程度再整理。
标记复制:只需对活着的对象遍历复制一次。堆空间会下降一半,长寿数据就比较麻烦。
解决方案:临时变量推荐复制,全部变量建议整理算法。
引用计数:将开销分摊在程序运行中。当系统部分不可用时,也可以回收部分内存,分布式中 十分有用。但是需要编译器和运行时系统支持,不然在指针操作非线程安全的情况 下有问题。引用计数频繁操作、原子性。
解决方案:延迟、合并引用计数,在开始、结束时保持数据一致性。
无法解决环状问题。
解决方案:偶尔追踪回收,或者实验删除法。
引用计数位数问题。
解决方案:偶尔追踪修正引用计数值。
非移动算法:标记清扫、引用计数。Bool、int
长期运行会使堆碎片化。
移动算法:标记整理、标记复制
开销大,不常使用,建议碎片率达到一定程度才建议使用。
分代回收:把对象分代进行处理,类似分段函数。可以有效的结合他们的优点、避免缺点。分 段函数的系数可以PID来动态调整。
同一代中可以进行分桶,桶满了才给升代。升代只需要移动指针就可以了。
超引用计数:引用计数管理年老代,复制回收管理年轻代。