CPython的内存分配策略

目录

 

1.内存管理从硬件到软件

2.CPython

3.全局解释锁GIL

4.CPython的内存分配策略


1.内存管理从硬件到软件

内存管理是应用程序读取和写入数据的过程。内存管理器确定将应用程序数据放置在何处。由于内存有限,管理器必须找到一些可用空间并将其提供给应用程序,提供内存的过程通常称为内存分配。另一方面,当不再需要数据时,可以将其删除或释放。

硬件(例如RAM或硬盘驱动器)上方的主要层之一是操作系统(OS),它执行(或拒绝)读取和写入内存的请求。在操作系统上方有一些应用程序,其中之一是默认的Python实现。Python代码的内存管理由Python应用程序处理。从物理硬件到CPython都有抽象层。操作系统(OS)提取物理内存并创建应用程序(包括Python)可以访问的虚拟内存层。

2.CPython

Python的默认实现是CPython,CPython实际上是用C编程语言编写的。Python是一种解释型编程语言。实际上,您的Python代码被编译为更多计算机可读指令,称为bytecode。运行代码时,虚拟机将解释这些指令。虚拟机类似于物理计算机,但是它们是通过软件实现的。它们通常会处理类似于汇编指令的基本指令

CPython是用C编写的,它解释Python字节码。这和内存管理有什么关系?内存管理算法和结构存在于Cpython代码中,存在于C中,为了理解Python的内存管理,必须对CPython本身有一个基本的了解。

Python中的所有内容都是一个对象,在CPython有一种结构叫做PyObject,PyObject是Python中所有对象的父级,它只包含两个内容:ob_refcnt:引用计数,ob_type:指向对象类型的指针

3.全局解释锁GIL

GIL是解决共享资源(例如计算机内存)的常见问题的解决方案。当两个线程尝试同时修改同一资源时,它们可以互相踩脚趾。最终结果可能是乱码,其中两个线程都没有达到他们想要的结果。

解决此问题的一种方法是,当线程与共享资源(书中的页面)进行交互时,在解释器上进行单个全局锁定。Python的GIL通过锁定整个解释器来实现这一点,这意味着另一个线程不可能踩到当前的解释器。当CPython处理内存时,它使用GIL来确保安全地这样做。

4.CPython的内存分配策略

Python将内存的一部分用于内部使用和非对象内存。另一部分用于对象存储(int、dict等)。注意,这样描述有点简单。CPython有一个对象分配器,负责在对象内存区域内分配内存。每当新对象需要分配或删除空间时,都会调用该方法。

分配器的内存级别为:区Arena、池pool,块block。

Arenas是最大的内存块,Python假定系统的页面大小为256 KB。Arena中有pool,pool是一个虚拟内存页(4 KB),这些pool被分成较小的内存块。pool由来自单个size class的内存块组成。每个pool都维护到同一size class的其他pool的双链接列表。这样,算法就可以很容易地找到给定内存块大小的可用空间,即使是在不同的池中。

pool本身必须在3种状态之一:usedfullemptyused pool有可用的块存储数据。full pool的块都被分配并包含数据。empty pool没有存储的数据,并且在需要时可被分配任何尺寸类的块。

当请求给定的块大小时,算法会在此used pool列表中检查该块大小的pool列表。但是什么时候使用空池呢?假设您的代码需要8字节的内存块。如果没有usedpools 8字节大小类的池,则将初始化一个新的empty池以存储8字节块,然后此新池将添加到used pools列表中,以便可用于将来的请求。假如一个full池释放了它的一些块,因为不再需要内存,该池将被添加回used pools其大小类的列表。

 如上图所示,在used pool中有指向空内存块的指针。块有三种状态:untouched未分配、free已分配但已被CPython释放,不再包含数据、allocated实际存有数据

Arenas本身并不像池那样具有明确的状态。相反,Arenas被组织成一个名为的双向链接列表usable_arenas。该列表按可用空闲池的数量排序。空闲池越少,Arena就越靠近列表的前面。

这意味着将选择数据最充分的区域来放置新数据。但是为什么不相反呢?为什么不将数据放在有最大可用空间的地方?

这就引出了真正解放记忆的想法。你会注意到我一直在用“free”这个词。原因是当一个块被认为是“空闲”的时候,内存实际上并没有被释放回操作系统。Python进程保持它的分配,并在以后用于新数据。真正释放内存会将其返回给操作系统使用。

Arena是唯一可以真正解放的地方。因此,有理由允许那些更接近于空的Arena变成空的。这样,可以真正释放内存块,从而减少Python程序的总体内存占用。

更多信息:什么是Python全局解释器锁(GIL)?   CPython的内存分配策略

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值