Python解释器PyPy新特色,让开发者自己控制垃圾回收时机以打造低延迟系统

讲求速度的Python的替代实例PyPy,最近整合了gc-disable分支,加入了支持低延迟回应特定事件的功能。不过,PyPy团队提到,这是非常专业的功能,一般PyPy的开发者可能用不到。

PyPy虚拟机管理内存所使用的垃圾回收器(Garbage Collector),会定期扫描整个堆(Heap)找寻无法访问的对象,并释放相对应的内存空间。虽然这样的方式听起来成本高昂,但事实上,其管理内存的总成本却远远低于使用引用计数的CPython。官方提到,尽管违反主动,但是非引用策略的主要优点是内存分配速度很快,特别是与基于malloc的分配器相比,而且解除分配年轻对象的成本趋近于零。

PyPy管理内存的总成本低于CPython,便是PyPy执行速度飞快的原因,但是这样的方式却存在很大的缺点,在CPython,内存管理的成本分散于程序执行之间,但是在PyPy中,内存管理成本却集中于垃圾回收器上,而这个成本造成可发现的程序停顿,足以中断用户程序的执行。

为了解决这个问题,从2013年开始,官方将垃圾回收器的工作拆分成一系列的步骤,用户程序可以穿插在步骤间执行,但是偶发回应延迟高的问题依然严重,在实际执行应用程序的过程,应用程序回应时间高峰甚至长达350到450毫秒,而新加入的gc-disable就是要来解决这个问题。

gc-disable由主要由两个功能组成,gc.disable()与gc.collect_step()。 gc.disable()会禁用垃圾回收器主要收集动作,但使用后内存使用量会无限增长,而gc.collect_step()是一个新函数,可用于手动执行单个增量式垃圾收集步骤。官方提到,gc.disable()仅禁用主要收集,而次要收集工作仍然会执行。

由于JIT的虚拟化,许多具有短暂且可预测生命周期的对象不会被分配(Allocate),最终大多数寿命较短的对象仍然会像往常一样被回收,因此实际上gc.disable()的影响并不如想象的糟糕。开发者应用这两项功能,可以控制应用程序在可接受的情况下执行。

官方提醒,使用gc.disable()并不会让应用程序神奇的加速,而是把垃圾收集的工作移动到别的时间点执行,但在特定的使用场景中,这项功能非常有用。现在gc-disable已在PyPy的Nightly版本中提供。