Shell's Home

Mar 31, 2011 - 1 minute read - Comments

python源码解析读书笔记(四)——杂项

1.GIL的影响

很多人讨论python性能的时候都提到一个概念,GIL。我在python源码中搜了一下,这个函数调用并不多,但是位置很要命。每个线程,生成的时候请求一下,退出的时候释放一下。在每次运行字节码前也会短暂的释放一下,让其他线程有获得运行的机会。说白了,除非程序显式的调用release_lock去释放资源,否则python是没有任何多线程能力的。这种机会并不很多,通常只发生在阻塞的时候。

而python原子化的粒度也比较清晰,就是每个字节码内部一定是原子的,字节码和字节码之间是非原子的。当我们操作l.append的时候,不用担心线程竞争导致数据结构损坏。但是如果我们操作del l[len(l)]的时候,存在发生异常的概率。

2.对象缓存池

python对小内存对象(碎片对象)提供了小内存对象缓存池。默认情况下,256字节以下的内存由小内存缓存池管理,以上的直接向系统申请,申请大小每8字节对齐。

对象缓存池的分配和收集技术采用了自由资源链表,在2.5之后,当某个尺度的资源不再需要时,会整体释放。

3.python的GC机制

python的GC机制是基于引用计数的,因此当引用计数归零,对象一定会被释放(如果是碎片对象,内存不一定直接释放,可能归对象缓存池)。

python的辅助垃圾收集算法是三色标记法和分代垃圾收集模型(generation),由于要跟踪所有的容器对象,因此容器对象上有跟踪链表。

4.字符编码处理方案

无论从何种来源,只要是字符串,并可能交给一个和当前代码并不紧密耦合的代码处理,就应当被转换为unicode。或者换一个更简洁的说法,应当使用unicode作为接口数据类型。

str对象是很难猜测编码的,当离开了数据源代码后,再分析编码是个不靠谱的方案。