09月17, 2020

30. 寸土寸金,两个指针玩出花

Python 为了实现 GC,在 Object 头部增加了两个额外的指针,Python 作为一种高级语言,对 “Object” 有着强烈的执念,同时也造成内存效率较低,现在在新增了两个指针,真可谓是 “儿到荒年饭量增,屋漏偏逢连夜雨”。Python 3.8 中为了降低这一影响,对这两个指针的使用细致到了按位复用的程度。对于 gc_prev 指针:

// Include/cpython/objimpl.h:68

// 0 位表示已经执行过 tp_finalize
#define _PyGC_PREV_MASK_FINALIZED  (1)
// 1 位表示对象正在被 GC
#define _PyGC_PREV_MASK_COLLECTING (2)

// 简单的 16 位操作系统, _PyGC_PREV_MASK 的值是 0b1111 1111 1111 1100
#define _PyGC_PREV_SHIFT           (2)
#define _PyGC_PREV_MASK            (((uintptr_t) -1) << _PyGC_PREV_SHIFT)

同样的,对于 gc_next 有:

// Modules/gcmodule.c:64

// 0 位表示 unreachable
#define NEXT_MASK_UNREACHABLE  (1)

这两个指针看起来像这样:

image.png

gc_next 只是将闲置的最低 1 位利用起来,而 gc_prev 则在回收阶段被直接用作 gc_refs 有效引用记数,一直到 collect 函数中才被重建为指针。

本文链接:http://www.thinkinpython.com/post/deep_python_vm_30.html

-- EOF --