一、内存的理解

你可以将计算机中的内存理解为一本为短期存储而设计的书。这本书中现在什么都没写,但最终不同的“作者”会来寻求空间,写入他们想写的故事。

由于他们之间不能彼此覆盖,他们在开始写入之前一定要向这本书的管理者申请,由管理者来决定他们写入到哪里。

由于这本书会存在很长的时间,书中的很多故事可能已经不再有意义。当没有人读或者引用故事,这些无意义的故事就会被删除,给新的故事腾出空间。

本质上,电脑内存很像是一本空的书。实际上,内存通常被叫做“固定长度的连续内存块”,所以这个类比是很贴切的。作者就像是不同的应用程序或者进程,需要在内存中存储数据。决定作者写内容位置的管理者则扮演各种各样内存管理器的角色。清除旧故事,给新作者提供空间的人就是垃圾回收机制。

二、内存管理:从硬件到软件

内存管理是应用读取、写入数据的流程。内存管理机制决定了在哪里存储应用数据。

就像是我们上面以书为类比,内存块也是有限的,管理机制必须要找出可用的空间并且将其提供给应用。这个提供内存的过程一般被称作内存分配。

另一方面,当数据不再被需要,那么数据可以被删除,或者被释放。但是释放到哪里呢?这个内存从哪里来的?

在你的计算机的某个位置,当你运行你的Python程序时,有一个实体硬件在存储数据。但是在对象实际到达硬件之前,Python代码要经过很多抽象层。

在硬件之上,其中一个主要的抽象层是默认的Python实现(在OS中内置或者你从http://python.org中下载)Python代码中的内存管理是由Python应用程序处理的。本文聚焦Python应用程序在内存管理中使用的结构和算法。

三、默认的Python实现

默认的Python实现,CPython是使用C语言写的。

是不是很震惊?一种语言是用另一种语言写的?好吧,这不是真的,但多少有点。

Python语言在Python参考文档里有详细的讲解,但是光靠文档并不能覆盖一切,我们还是需要一些东西来编译实际代码。我们也需要在计算机上实际执行编译后的代码。默认的Python实现满足这两个要求,它将你的Python代码转化为指令并且将其运行在虚拟机上。

Python是解释型语言,你的Python代码实际上被编译成更底层,更对计算机友好的bytecode指令。当你运行你的代码时,这些指令被虚拟机编译了。你见过.pyc文件或者__pycache__文件夹吗?那就是被虚拟机编译后的bytecode代码。

必须指出,除了CPython之外,还有别的Python实现。Ironpython编译后在Microsoft 的公共语言运行时上运行。Jython编译后成为Java bytecode,在Java虚拟机上运行,还有PyPy,但这个Python实现值得用一篇文章专门介绍,此处不提。

为了理解Python内存管理,我们将聚焦于Python的默认实现——Cpython中所实现的内存管理。本文中涉及到的知识适用于目前的通用版本——Python3.7

好了,我们知道CPython是用C写的,并且编译为Python bytecode,这和内存管理有什么联系呢?是这样的——内存管理算法和结构存在于CPython代码中,用C写的。为了理解Python中的内存管理,我们需要对CPython有一些基本了解。

CPython是用C写的,它本身并不支持面向对象编程。正因如此,在CPython中有很多有趣的设计。你可能听说过Python中一切皆是对象,甚至诸如int、str这样的类型。确实,在CPython的实现级别是这样的。有一个结构叫做PyObject,在CPython中其他object都在使用它。

C中的一个或者多个结构是将不同数据类型组合在一起的自定义数据类型。与面向对象的语言相比,就像是具有属性且没有方法的类。PyObject,所有Python中对象的老祖宗,仅仅包含如下两个部分:

  • ob_refcnt:引用计数
  • ob_type: 指针

引用计数用于垃圾回收机制。你现在有一个指针,指向实际对象类型。该对象类型只是另一种用于描述Python对象的结构(例如dict或者int)

每个对象都有自己的特定对象的内存分配器,该分配器知道如何获取存储该对象的内存,每个对象也有特定对象的内存释放器,用于释放不再被需要的内存。

在我们所有关于分配和释放内存的讨论中,有一个重要的因素。内存是计算机中被共享的资源,如果不同的进程同时写入同一位置,糟糕的事情就会发生。

四、全局解释器锁(GIL)

GIL是在解决共享资源,像是内存这类型的共性问题的有效解决办法。当两个线程同时想要修改相同的资源,他们可能会互相“踩脚趾”,最终的结果可能是乱码,在乱码中,两个线程都没有得到想要的结果。

再考虑一下我们那个用书比作内存的比喻。假设两个作者都固执地一定认为该轮上他来写了,而且他们都要写到书的同一页上。他们忽略了其他人也在创作故事,那么结果就是一页上两个故事相互重叠,整个页面完全不可读。

这个问题的解决办法之一是:在一个线程与共享资源交互时,使用单一的全局解释器锁将该资源上锁。也就是说,同一时间只有一个作者可以写作。

Python的全局解释器锁通过锁住整个解释器来实现这一点。这意味着另一个线程不可能踩到当前的解释器。当CPython处理内存时,使用GIL锁来确保安全。

这种方法有利有弊,也在Python社区引起了激烈讨论。

关于全局解释器锁:

What is the Python Global Interpreter Lock (GIL)? – Real Python​realpython.com

python内存管理_Python内存管理(一):预备知识相关推荐

  1. python 内存分析_python内存管理分析

    本文较为详细的分析了python内存管理机制.分享给大家供大家参考.具体分析如下: 内存管理,对于Python这样的动态语言,是至关重要的一部分,它在很大程度上甚至决定了Python的执行效率,因为在 ...

  2. python会不会出现内存泄露_Python内存泄漏和内存溢出的解决方案

    一.内存泄漏 像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题. 对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是 ...

  3. python 内存溢出_python内存溢出

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 这里整理了一次内存泄漏的问题通常我们写python程序的时候也很少关注内存这个问 ...

  4. python多线程内存溢出_Python内存泄漏和内存溢出的解决方案

    一.内存泄漏 像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题. 对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是 ...

  5. python tuple用处_Python入门之最少必要知识

    学习任何的新知识和新技能,基础都是最关键的,就像小的时候学习语文,一定是从拼音开始学起,这是之后学习汉字的基本功,是必须掌握的最基础知识.那学习Python又有哪些最少必要知识呢? 学习Python永 ...

  6. python的内存管理_python如何管理内存?

    介绍 内存管理是有效分配,重新分配和协调内存的过程,以便所有不同的进程都能平稳运行并可以最佳地访问不同的系统资源.内存管理还涉及清除不再访问的对象的内存. 在Python中,内存管理器通过定期运行以清 ...

  7. python内存池_python内存监控工具memory_profiler和guppy的用法详解

    python内存监控工具memory_profiler和guppy的用法详解 发布时间:2020-08-21 19:44:58 来源:脚本之家 阅读:123 python2.7在内存管理上相比pyth ...

  8. python 多态 锁_python 上下文管理器,多态,数据锁定与自省,

    python 上下文管理器,多态,数据锁定与自省, 前文课题 通过装饰器来实现单例模式 通过类实现一个通用装饰器,皆可以装饰函数也可装饰类,即可有参也可无参 描述 new str repr call ...

  9. python包管理_Python包管理整理:setuptoo

    setuptool管理python相关的包 一.介绍 setuptool管理python相关的包的工具.这些包是zip格式发布,但是后缀一般都是.egg setuptool能解决python包的依赖关 ...

最新文章

  1. 创建一个栈存储结构,并且写入一些对栈的基本的操作
  2. ISME:污水厂抗性组受细菌组成和基因交换驱动且出水中抗性表达活跃
  3. 机器学习算法一览,应用建议与解决思路
  4. 电脑有摄像头吗_知道ip地址就能入侵摄像头吗?
  5. SAP BPC系统架构
  6. java基础—Hashtable,HashMap,TreeMap的区别
  7. blender使用_用Blender教青少年3D动画
  8. 根本没人买!又一品牌宣布不再做手机了...
  9. mybatis中转义 大于,小于,大于等于,小于等于
  10. Qt4_发送和接收UDP数据报
  11. python的枚举函数_enumerate()函数~~返回一个枚举对象
  12. python IO文件处理
  13. Mirth Connect 源码用eclipse启动
  14. [转]如何学好windows c++编程 学习精髓(收集,整理)
  15. python学期总结
  16. VCS建立仿真生成DVE波形
  17. python (win32com) 批量删除 word (docx, doc) 中所有页眉、页脚 (Word.Application, Word.Basic)
  18. 图数据库——大数据时代的高铁
  19. SuperSocket.WebSocket WebSocketServer设置文本编码
  20. 秋月之谋:黄金1504空再度击穿千五一线,原油反抽迎战前高阻力!

热门文章

  1. 设置数字范围的html语言,JavaScript奇技淫巧44招【实用】
  2. php验证码 php中文网,ThinkPHP 使用不同风格及中文的验证码
  3. 1044 火星数字 PAT乙级 (C++)
  4. 【渝粤教育】广东开放大学 Photoshop 图像处理 形成性考核 (24)
  5. 【渝粤题库】国家开放大学2021春2321物流学概论题目
  6. Time-of-Flight技术在距离测量和定位上的应用
  7. 对c语言字符数组描述错误的是,下述对C语言字符数组的描述中错误的是( )。
  8. java se 定时任务_Java实现定时任务的三种方法
  9. (0.2)HarmonyOS鸿蒙开发工具DevEco Studio工程文件目录结构
  10. 重温1 Android系统架构及版本