Python内存分配
一、前言
大多数编译型语言,变量在使用前必须先声明,其中C语言更加苛刻:变量声明必须位于代码块最开始,且在任何其他语句之前。其他语言,想C++和java,允许“随时随地”声明变量,比如,变量声明可以在代码块的中间,不过仍然必须在变量被使用前声明变量的名字和类型。在Python中,无序此类显式变量声明语句,变量在第一次被赋值时自动声明。和其他大多数语言一样,变量只有被创建和赋值后才能被使用。
# 变量未声明
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined #变量一旦被赋值,就可以通过变量名来访问它 >>> x=1
>>> y="It's wonderful."
>>> x
1
>>> y
"It's wonderful."
二、动态类型
Python中不但变量名无需事先声明,而且也无需类型声明。在Python语言中,对象的类型和内存占用都是运行时确定的。尽管代码被编译成字节码,Python仍然是一种解释型语言。在赋值时解释器会根据语法和右侧的操作数来决定新对象的类型。在对象创建后,一个该对象的应用会被赋值给左侧的变量。
三、内存分配
作为一个负责任的程序员,我们知道在为变量分配内存时,是在借用系统资源,在用完之后,应该释放借用的系统资源。Python解释器承担了内存管理的复杂任务,这大大简化了应用程序的编写。
3.1 引用计数
要保持追踪内存中的对象,Python使用了引用计数这一简单技术。也就是说Python内部记录着所有使用中的对象 各有多少引用。一个内部跟踪变量,称为引用计数器。每个对象各有多少个引用,简称引用计数。当对象被创建时,就创建了一个引用计数,当这个对象不再需要时,也就是说,这个对象的引用计数变为0时,它被垃圾回收。(并不是100%这样)
3.2 增加引用计数
当对象被创建并赋值给变量时,该对象的引用计数就被设置为1。
当同一个变量又被赋值给其他变量时,或作为参数传递给函数、方法或类实例,或者被赋值为一个窗口对象的成员时,该对象的一个新的引用,或者称为别名,就被创建(则该对象的引用计数就自动加1)。
如下代码:
>>> x = 3
>>> y = x
语句x=3我们将3赋值给x。x是第一个引用,因此,该对象的引用计数被设置为1。语句y=x创建了一个指向同一对象的别名y。事实上并没有为y创建一个新的对象,而是该对象的引用计数增加了一次(变成了2)。这是对象引用计数增加的方式之一。还有一些其他的方式也能增加对象的引用计数,比如该对象作为参数被函数调用或这个对象被加入到某个列表等对象当中。
总之,对象的引用计数增加是:
- 对象被创建
x = 3
- 另外的别名被创建
y = x
- 作为参数传递给函数
foo(x)
- 成为容器对象的一部分
mylist = [1,2,x,'xyz']
3.3 减少引用计数
当对象的引用被销毁时,引用计数会减小。最明显的例子就是当引用离开其作用范围时,这种情况最经常出现在函数运行结束时,所有的局部变量都被自动销毁,对象的引用计数也就随之减少。
当变量被赋值给另外一个对象时,原对象的引用计数也会自动减1:
>>> foo = 'xyz'
>>> bar = foo
>>> foo = 123
当字符串对象“xyz”被创建并赋值给foo时,它的引用计数是1。当增加一个别名bar时,引用计数变成了2。不过当foo被重新赋值给整型对象123时,xyz对象的引用计数自动减1,又重新变成了1。
其他造成对象引用计数减少的方式包括使用del语句删除一个变量,或者当一个对象被移出一个窗口对象时。
对象引用计数减少的情况:
- 一个本地引用离开了其作用的范围。比如foo() 函数结束时。
- 对象别名被显式销毁
del y
- 对象的一个别名被赋值给其他对象
x = 123
- 对象被从一个窗口对象中移除
mylist.remove(x)
- 窗口对象本身被销毁
del mylist
四、垃圾收集
不再使用的内存会被一种称为垃圾收集的机制释放。像上面说的,虽然解释器跟踪对象的引用计数,但垃圾收集器负责释放内存。垃圾收集器是一块独立代码,它用来寻找计数为0的对象。它也负责检查那些虽然引用计数大于0但也应该被销毁的对象。特定情形会导致循环引用。
Python内存分配的更多相关文章
- Python 内存分配时的小秘密
Python 中的sys 模块极为基础而重要,它主要提供了一些给解释器使用(或由它维护)的变量,以及一些与解释器强交互的函数. 本文将会频繁地使用该模块的getsizeof() 方法,因此,我先简要介 ...
- Python内存管理机制-《源码解析》
Python内存管理机制 Python 内存管理分层架构 /* An object allocator for Python. Here is an introduction to the layer ...
- python的内存分配
一.前言 大多数编译型语言,变量在使用前必须先声明,其中C语言更加苛刻:变量声明必须位于代码块最开始,且在任何其他语句之前.其他语言,想C++和java,允许“随时随地”声明变量,比如,变量声明可以在 ...
- 装逼手册之 python中的内存分配的小秘密
装逼手册之 python中的内存分配的小秘密 虽然我们现在得益于时代和技术的发展,不用再担心内存的问题:但是遥想当年,都是恨不得一个钢镚掰成俩份用,所以我就想深入了解一下,在python中内存分配的一 ...
- python的list内存分配算法
前提:python为了提高效率会为list预先分配一定的内存空间供其使用,避免在每次append等操作都去申请内存,下面简单分析下list的内存分配算法,主要就是两段. 1.当没有元素时,newsiz ...
- JVM的内存分配与垃圾回收策略
自动内存管理机制主要解决了两个问题:给对象分配内存以及回收分配给对象的内存. >>垃圾回收的区域 前面的笔记中整理过虚拟机运行数据区,再看一下这个区域: 注意在这个Runtime Data ...
- python内存管理机制
主要分为三部分: (1)内存池机制(2)引用计数(3)垃圾回收 (1)内存池机制对于python来说,对象的类型和内存都是在运行时确定的,所以python对象都是动态类型简单来说,python内存分为 ...
- Python内存解析浅学
1.内存管理 首先理解变量,和内存特性 1. Python中无须声明变量, 2. 无须指定类型 3. 不用关心内存管理 4. 变量名会被回收 5. ...
- 转发:[Python]内存管理
本文为转发,原地址为:http://chenrudan.github.io/blog/2016/04/23/pythonmemorycontrol.html 本文主要为了解释清楚python的内存管理 ...
随机推荐
- Professional Books
Machine Learning: Pattern Recognition and Machine Learning(PRML) https://mqshen.gitbooks.io/p ...
- 遗传算法框架GAFT优化小记
前言 前段时间一直在用自己写的遗传算法框架测试算法在优化力场参数的效果,但是跑起来效率很慢,因为适应度函数需要调用多次力场程序计算能量,但是还是比我预想中的慢我也没有及时对程序进行profiling和 ...
- Python 并行分布式框架:Celery 超详细介绍
本博客摘自:http://blog.csdn.net/liuxiaochen123/article/details/47981111 先来一张图,这是在网上最多的一张Celery的图了,确实描述的非常 ...
- Factorials 阶乘(思维)
Description N 的阶乘写作N!表示小于等于N的所有正整数的乘积.阶乘会很快的变大,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了.你的任务是 找到阶乘最后面的非零位.举 ...
- 1014-C程序的语法树
- c# 免费版pdf转word尝试
链接:https://pan.baidu.com/s/1Dwuezo6YGe9CdlSyrwQyNg 密码:c81a 1.安装此程序 2.在安装文件的bin下拷贝dll: 3.代码引用 private ...
- Myeclipse错误:Errors occurred during the build. Errors running builder 'DeploymentBuilder' on project ...解决方法
解决办法:1.首先关闭MyEclipse工作空间.2.然后删除工作空间下的“/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.gen ...
- WPF和Expression Blend开发实例:Loading动画
今天来点实际的,项目中可以真实使用的,一个Loading的动画,最后封装成一个控件,可以直接使用在项目中,先上图: 整个设计比较简单,就是在界面上画18个Path,然后通过动画改变OpacityMas ...
- 词法分析用c++实现的
#include<stdio.h>#include<string.h>int i,j,k,sign,flag,number,run;char ch;char word[10]; ...
- Servlet处理表单