python内存动态分配过程详解


Posted in Python onJuly 15, 2019

一、前言

大多数编译型语言,变量在使用前必须先声明,其中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

python内存动态分配过程详解

语句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爬虫入门教程--正则表达式完全指南(五)
May 25 Python
python使用tornado实现简单爬虫
Jul 28 Python
Python socket模块实现的udp通信功能示例
Apr 10 Python
python安装scipy的方法步骤
Jun 26 Python
如何安装2019Pycharm最新版本(详细教程)
Sep 26 Python
python对象销毁实例(垃圾回收)
Jan 16 Python
解决Tensorboard可视化错误:不显示数据 No scalar data was found
Feb 15 Python
python:批量统计xml中各类目标的数量案例
Mar 10 Python
基于python实现坦克大战游戏
Oct 27 Python
python3 hdf5文件 遍历代码
May 19 Python
你需要掌握的20个Python常用技巧
Feb 28 Python
对象析构函数__del__在Python中何时使用
Mar 22 Python
python实现动态数组的示例代码
Jul 15 #Python
python移位运算的实现
Jul 15 #Python
python与C、C++混编的四种方式(小结)
Jul 15 #Python
解决Python3 控制台输出InsecureRequestWarning问题
Jul 15 #Python
python导包的几种方法(自定义包的生成以及导入详解)
Jul 15 #Python
Python将文字转成语音并读出来的实例详解
Jul 15 #Python
解决win7操作系统Python3.7.1安装后启动提示缺少.dll文件问题
Jul 15 #Python
You might like
星际争霸兵种名称对照表
2020/03/04 星际争霸
德生9700DX电路分析
2021/03/02 无线电
php PDO中文乱码解决办法
2009/07/20 PHP
php下将图片以二进制存入mysql数据库中并显示的实现代码
2010/05/27 PHP
php Static关键字实用方法
2010/06/04 PHP
允许phpmyadmin空密码登录的配置方法
2011/05/29 PHP
在Laravel框架里实现发送邮件实例(邮箱验证)
2016/05/20 PHP
laravel通用化的CURD的实现
2019/12/13 PHP
汉化英文版的Dreamweaver CS5并自动提示jquery
2010/11/25 Javascript
50款非常棒的 jQuery 插件分享
2012/03/29 Javascript
用示例说明filter()与find()的用法以及children()与find()的区别分析
2013/04/26 Javascript
红米手机抢购的js代码
2014/03/10 Javascript
Nodejs中session的简单使用及通过session实现身份验证的方法
2016/02/04 NodeJs
js求数组中全部数字可拼接出的最大整数示例代码
2017/08/25 Javascript
详解在express站点中使用ejs模板引擎
2017/09/21 Javascript
解决vue+webpack打包路径的问题
2018/03/06 Javascript
详解Node使用Puppeteer完成一次复杂的爬虫
2018/04/18 Javascript
JavaScript进阶(二)词法作用域与作用域链实例分析
2020/05/09 Javascript
浅谈终端直接执行py文件,不需要python命令
2017/01/23 Python
Python错误提示:[Errno 24] Too many open files的分析与解决
2017/02/16 Python
简单了解什么是神经网络
2017/12/23 Python
scrapy spider的几种爬取方式实例代码
2018/01/25 Python
利用python将json数据转换为csv格式的方法
2018/03/22 Python
caffe binaryproto 与 npy相互转换的实例讲解
2018/07/09 Python
django中ORM模型常用的字段的使用方法
2019/03/05 Python
Pyinstaller打包.py生成.exe的方法和报错总结
2019/04/02 Python
python开启debug模式的方法
2019/06/27 Python
Python Django切换MySQL数据库实例详解
2019/07/16 Python
Python爬虫中Selenium实现文件上传
2020/12/04 Python
HTML5标签使用方法详解
2015/11/27 HTML / CSS
美国和加拿大计算机和电子产品购物网站:TigerDirect.com
2019/09/13 全球购物
会计毕业生求职简历的自我评价
2013/10/20 职场文书
委托书范文
2014/04/02 职场文书
交通事故赔偿协议书范本
2014/04/15 职场文书
一篇文章带你复习java知识点
2021/06/28 Java/Android
MySQL中TIMESTAMP类型返回日期时间数据中带有T的解决
2022/12/24 MySQL