CPython源码包的功能分类
此文是按照源码Python3.9来写,其中有些assert语句与一些不必要的宏字段会删除,保留核心的逻辑并添加注释,方便自己和大家理解。在代码中都会注明源码出处方便大家完整阅读。
目录 | 概要 |
---|---|
Demo | 采用了Python的演示应用程序 |
Doc | 文档 |
Grammer | Python的语法文件 |
Include | 编译Python时引用的各种头文件 |
Lib | 标准附加库 |
Mac | Mac用的工具等 |
Misc | 很多文件的集合(如gdbinit和vimrc等) |
Modules | Python的C语言扩展模块 |
Objects | Python的对象用的C语言代码 |
PC | 依存于OS等环境的程序 |
PCbuild | 构造Win32和x64时使用 |
Parser | Python用的解析器 |
Python | Python的核心 |
Python的内存管理架构
Python是一门动态的、一切皆对象的语言,这些内存申请可能会产生大量小的内存,为了加快内存操作和减少内存碎片化,使用Python自己的内存管理器,叫PyMalloc。
- # Objects/obmalloc.c 代码注释
- /* An object allocator for Python.
- Here is an introduction to the layers of the Python memory architecture,
- showing where the object allocator is actually used (layer +2), It is
- called for every object allocation and deallocation (PyObject_New/Del),
- unless the object-specific allocators implement a proprietary allocation
- scheme (ex.: ints use a simple free list). This is also the place where
- the cyclic garbage collector operates selectively on container objects.
- Object-specific allocators
- _____ ______ ______ ________
- [ int ] [ dict ] [ list ] … [ string ] Python core |
- +3 | <—– Object-specific memory —–> | <— Non-object memory —> | # 对象特有的内存分配器
- _______________________________ | |
- [ Python's object allocator ] | |
- +2 | ####### Object memory ####### | <—— Internal buffers ——> | # Python对象分配器
- ______________________________________________________________ |
- [ Python's raw memory allocator (PyMem_ API) ] |
- +1 | <—– Python memory (under PyMem manager's control) ——> | | # Python低级内存分配器
- __________________________________________________________________
- [ Underlying general-purpose allocator (ex: C library malloc) ]
- 0 | <—— Virtual memory allocated for the python process ——-> | # 通用的基础分配器(如glibc的malloc等)
- =========================================================================
- _______________________________________________________________________
- [ OS-specific Virtual Memory Manager (VMM) ]
- -1 | <— Kernel dynamic storage allocation & management (page-based) —> | # OS特有的虚拟内存管理器
- __________________________________ __________________________________
- [ ] [ ]
- -2 | <— Physical memory: ROM/RAM —> | | <— Secondary storage (swap) —> | # 物理内存和交换目的地(如HDD等)
- */
- PyDict_New() // 第三层
- PyObject_GC_New() // 第二层
- PyObject_Malloc() // 第二层
- new_arena() // 第一层
- malloc() // 第零层
- ////////////////////////////////////////以下2层属于操作系统范畴,不在讨论范围/////////////////////////////////
通用的基础分配器(0层)
512字节是CPython的阈值
- //Objects/obmalloc.c
- #define SMALL_REQUEST_THRESHOLD 512
- #define NB_SMALL_SIZE_CLASSES (SMALL_REQUEST_THRESHOLD / ALIGNMENT)
- /* Largest positive value of type Py_ssize_t. */
- #define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1))
- static void *
- _PyObject_Malloc(void *ctx, size_t nbytes)
- { // 走Python的分配器,函数进去就会有判断(0,512]的才使用
- void* ptr = pymalloc_alloc(ctx, nbytes);
- if (LIKELY(ptr != NULL)) {
- return ptr;
- }
- // 大于512字节走C的malloc,函数进去进做了越界判断,Py_ssize_t为阈值
- ptr = PyMem_RawMalloc(nbytes);
- if (ptr != NULL) {
- raw_allocated_blocks++;
- }
- return ptr;
- }
- 0: 直接调用 malloc 函数
- 1 ~ 512: 由Python的内存池负责分配,内存池以内存尺寸进行划分
- 512以上: 直接调动 malloc 函数
在源代码中以PyMem_为前缀的所有函数是封装C语言提供给Python语法使用的,其核心使用的就是第0层malloc之类的C库函数。
通常Python没有对小块内存的内存池的大小做任何的限制
当Python在WITH_MEMORY_LIMITS编译符号打开的背景下进行编译时,Python内部的另一个符号会被激活,这个名为SMALL_MEMORY_LIMIT的符号限制了整个内存池的大小,同时,也就限制了可以创建的arena的个数。
在默认情况下,不论是Win32平台,还是unix平台,这个编译符号都是没有打开的,所以通常Python都没有对小块内存的内存池的大小做任何的限制。