講求速度的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版本中提供。


Advertisement

更多 iThome相關內容