python内存机制

来源:互联网 发布:java分布式开发面试题 编辑:程序博客网 时间:2024/06/11 03:35

先从较浅的层面来说,Python的内存管理机制可以从三个方面来讲

(1)垃圾回收

(2)引用计数

(3)内存池机制

一、垃圾回收:

python不像C++,Java等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值。对Python语言来讲,对象的类型和内存都是在运行时确定的。这也是为什么我们称Python语言为动态类型的原因(这里我们把动态类型可以简单的归结为对变量内存地址的分配是在运行时自动判断变量类型并对变量进行赋值)。

二、引用计数:

Python采用了类似Windows内核对象一样的方式来对内存进行管理。每一个对象,都维护这一个对指向该对对象的引用的计数。

x = 3.14

y = x

 

我们首先创建了一个对象3.14, 然后将这个浮点数对象的引用赋值给x,因为x是第一个引用,因此,这个浮点数对象的引用计数为1. 语句y = x创建了一个指向同一个对象的引用别名y,我们发现,并没有为Y创建一个新的对象,而是将Y也指向了x指向的浮点数对象,使其引用计数为2

我们可以很容易就证明上述的观点:

>>> a = 4>>> b =a>>> id(b)1840301904>>> id(a)1840301904>>>

 三、内存池机制:

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的地址变得不再相同


内存管理

包括:

  • 变量无须事先声明
  • 变量无须指定类型
  • 不用关心内存管理
  • 变量名会被"回收"
  • del 语句能够直接释放资源

变量定义

python中, 变量在第一次被赋值时自动声明, 和其它语言一样, 变量只有被创建和赋值后才能被使用

动态类型

变量名无须事先声明, 也无须类型声明
对象的类型和内存占用都是运行时确定的

内存分配

python解释器会自动进行内存管理, 不用开发人员去关心

引用计数

  • 要保持追踪内存中的状态, python使用了引用计数, 就是python内部记录着所有使用中的对象各有多少引用.
  • 一个内部跟踪变量, 称为一个引用计数器, 至于每个对象各有多少引用, 简称引用计数, 当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0时, 它被垃圾回收

增加引用计数

  • 当对象被创建赋值给变量时, 该对象的引用计数就被设置为1
  • 当同一个对象又被赋值给其他变量时, 或作为参数传递给函数, 方法或类实例时, 或者被赋值为一个窗口对象的成员时, 该对象的一个新的引用, 或者作为别名, 就被创建.

减少引用计数

当对象的引用被销毁时, 引用计数会减少, 明显的例子就是当引用离开其作用范围时, 这种情况最经常出现在函数运行结束时, 所有局部变量都被自动销毁, 对象的引用计数也就减少

垃圾收集

不再被使用的内存会被一种称为垃圾收集的机制释放
注: 解释器跟踪对象的引用计数, 垃圾回收机制负责释放内存, 垃圾收集器是一块独立代码, 它用来寻找引用计数为0的对象, 它也负责检查虽然引用计数大于0但是也应该被销毁的对象


  • 引用语义: python中在变量里保存值(对象)的引用, 采用这种方式, 变量所需的存储空间大小一致, 因为其只需要保存一个引用
  • 值语义变量的值直接保存在变量的存储区里, 这样一个整数类型的变量就需要保存一个整数所需的空间, 一个浮点数变量就需要足够的空间存储一个浮点数. C中就是值语义
原创粉丝点击