垃圾回收
Python 不像 C++,Java 等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值。对 Python 语言来讲,对象的类型和内存都是在运行时确定的。这也是为什么我们称 Python 语言为动态类型的原因(这里我们把动态类型可以简单的归结为对变量内存地址的分配是在运行时自动判断变量类型并对变量进行赋值)。
引用计数
Python 采用了类似 Windows 内核对象一样的方式来对内存进行管理。每一个对象,都维护这一个对指向该对对象的引用的计数。当变量被绑定在一个对象上的时候,该变量的引用计数就是 1,(还有另外一些情况也会导致变量引用计数的增加),系统会自动维护这些标签,并定时扫描,当某标签的引用计数变为 0 的时候,该对就会被回收。
内存池机制
Python 的内存机制以金字塔行,1、2 层主要有操作系统进行操作
第 0 层是 C 中的 malloc,free 等内存分配和释放函数进行操作
第 1 层和第 2 层是内存池,有 Python 的接口函数 PyMem_Malloc 函数实现,当对象小于 256K 时由该层直接分配内存
第 3 层是最上层,也就是我们对 Python 对象的直接操作
在 C 中如果频繁的调用 malloc 与 free 时,会产生性能问题.再加上频繁的分配与释放小块的内存会产生内存碎片。
Python 在这里主要干的工作有:
如果请求分配的内存在 1~256 字节之间就使用自己的内存管理系统,否则直接使用 malloc。
这里还是会调用 malloc 分配内存,但每次会分配一块大小为 256k 的大块内存。
经由内存池登记的内存到最后还是会回收到内存池,并不会调用 C 的 free 释放掉以便下次使用。对于简单的 Python 对象,例如数值、字符串,元组(tuple 不允许被更改)采用的是复制的方式(深拷贝?),也就是说当将另一个变量 B 赋值给变量 A 时,虽然 A 和 B 的内存空间仍然相同,但当 A 的值发生变化时,会重新给 A 分配空间,A 和 B 的地址变得不再相同。
当退出 Python 时是否释放所有内存分配?
循环引用其他对象或引用自全局命名空间的对象的模块,在 Python 退出时并非完全释放。
另外,也不会释放 c 库保留的内存部分