Python原理 -- 内存管理
语言的内存管理是语言设计的一个重要方面. 它是决定语言性能的重要因素. 无论是 c语言 的手工管理, 还是 Java 的垃圾回收, 都成为语言最重要的特种.
以下以 python 为例, 说明一门动态语言类型的, 面向对象的语言的内存管理方式.
对象的内存使用
赋值语句
`a = 1` 数字 1 是一个对象, a 是一个引用. 利用赋值语句, 引用 a 指定对象 1 .
python 是动态类型的语言, 引用与对象分离.
id() 返回对象的内存地址.
在Python中,整数和短小的字符,Python都会缓存这些对象,以便重复使用。当我们创建多个等于1的引用时,实际上是让所有这些引用指向同一个对象。
使用 is 判断引用所指向的对象是否相同 :
a = 1
b = 1
a is b
在Python中,每个对象都有存有指向该对象的引用总数,即引用计数(reference count)。
使用 sys.getrefcount() 来查看某个对象的引用计数. *当使用某个引用作为参数,传递给getrefcount()时,参数实际上创建了一个临时的引用。因此,getrefcount()所得到的结果,会比期望的多1。*
from sys import getrefcount a = [1, 2, 3]
print(getrefcount(a)) # 2 b = a
print(getrefcount(a)) # 3
print(getrefcount(b)) # 3
对象引用对象
python 中的 容器对象(container) 比如 表, 字典等, 可以包含多个对象. 实际上, 容器对象中包含的并不是元素对象本身, 是指向各个元素对象的引用.
对象引用对象是 python 最基本的构成方式. 即使是 a=1 这一赋值方式, 实际上是让字典的一个键 "a" 的元素引用整数对象. 该字典对象用于记录所有的全局引用.
globals() # 查看全局引用字典.
垃圾回收
从基本原理上,当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了。比如某个新建对象,它被分配给某个引用,对象的引用计数变为1。如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。
垃圾回收时, Python 不能进行其他的任务. 频繁的来及回收将大大降低 python 的工作效率. 如果内粗怒中的对象不多就没有必要启动垃圾回收. 所有 python 只会在特定条件下, 自动启动垃圾回收. 当 python 运行时, 会记录其中分配对象(object allocation)和取消分配对象(object deallocation)的次数, 当两者的差值高于某个阈值时, 启动垃圾回收.
查看 阈值 :
import gc
print gc.get_threshold() # (700, 10, 10) gc.set_threshold(700, 10, 5) # 设置 阈值. gc.collect() # 手动启动垃圾回收. 返回 (700,10,10) 中, 后面的 两个 10 与 分代回收相关的阈值, 700 为垃圾回收启动的阈值.
分代回收
Python 同时采用 分代(generation) 回收的策略.
分代回收的基本假设 : 存活时间越久的对象, 越不可能在后面的程序中变成垃圾.
我们的程序往往会产生大量的对象, 许多对象很快产生和消失, 但也有一些对象长期被使用. 出于信任和效率, 对于这样一些 "长寿" 的对象, 我们相信他们的用处, 所以减少在垃圾回收中扫描他们的频率.
Python 将所有的对象分为 0,1,2 三代. 所有的新建对象都是 0 代对象. 当某一代对象经历过垃圾回收, 依然存活, 那么, 他就被归为下一代对象. 垃圾回收启东时, 一定会扫描所有的 0 代对象. 如果 0 代经过一定次数垃圾回收, 那么就启动对 0 代和 1 代的扫描清理. 当 1 代也经历了一定次数的垃圾回收, 那么启动对 0,1,2 , 即所有对象进行扫描. 这两个 次数 就是上面 get_threshold() 返回的 (700,10,10) 后面的两个10, 即 每 10 次 0 代垃圾回收, 会配合 1 次 1 代的垃圾回收, 而每 10 次 1 代的垃圾回收, 才会有 1 次 2 代垃圾回收. 可以通过 gc.set_threshold() 来调整.
Python采取了一种相对简单的垃圾回收机制,即引用计数,并因此需要解决孤立引用环的问题。
Python原理 -- 内存管理的更多相关文章
- python学习笔记10(Python的内存管理)
用这张图激励一下自己,身边也就只有一位全栈数据工程师!!! 32. Python的内存管理 1. 对象的内存使用 对于整型和短字符串对象,一般内存中只有一个存储,多次引用.其他的长字符串和其他对象 ...
- python的内存管理机制
先从较浅的层面来说,Python的内存管理机制可以从三个方面来讲 (1)垃圾回收 (2)引用计数 (3)内存池机制 一.垃圾回收: python不像C++,Java等语言一样,他们可以不用事先声明变量 ...
- day21(1)---python的内存管理
垃圾回收机制: 不能被程序访问到的数据,就称之为垃圾. 引用计数:引用计数是用来记录值的内存地址被记录的次数的 每一次对值地址的引用都可以使得该值的引用计数+1 每一次对值地址的释放都可以使得该值的引 ...
- python的内存管理与垃圾回收机制学习
一.python内存申请: 1.python的内存管理分为六层:最底的两层有OS控制.第三层是调用C的malloc和free等进行内存控制.第四层第五层是python的内存池.最上层使我们接触的直接对 ...
- python的内存管理机制(zz)
本文转载自:http://www.cnblogs.com/CBDoctor/p/3781078.html 先从较浅的层面来说,Python的内存管理机制可以从三个方面来讲 (1)垃圾回收 (2)引用计 ...
- Python的内存管理、命名规则、3个特性讲解
理解变量: 变:现实世界中的状态是会发生改变的 量:衡量/记录现实世界中的状态,让计算机能够像人一样去识别世间万物(例如:一个人的身高.体重等这些信息) 为什么要变量: 程序执行的本质就是一系列状态的 ...
- Python深入06 Python的内存管理
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 语言的内存管理是语言设计的一个重要方面.它是决定语言性能的重要因素.无论是C语言的 ...
- 【转】python的内存管理机制
http://developer.51cto.com/art/201007/213585.htm 内存管理,对于Python这样的动态语言,是至关重要的一部分,它在很大程度上甚至决定了Python的执 ...
- Theano教程:Python的内存管理
在写大型程序时候的一大挑战是如何保证最少的内存使用率.但是在Python中的内存管理是比较简单的.Python显示分配内存,使用引用计数系统管理对象,当指向某一个对象的引用数变为 0 的时候,该对象所 ...
随机推荐
- smart beta
本文来至人大经济论坛,http://bbs.pinggu.org/thread-3151691-1-1.html 众所周知,beta在CAPM模型中衡量了相对于持有整个市场所带来的风险溢价(risk ...
- final的用法
先来看一段代码 class Car extends Vehicle { public static void main (String[] args) { new C ...
- 如果非的让我引起大家的狂拍,那我说一句PHP是世界上最好的语言?
如果你进来了,那就达到了我的目的. 不知不觉.net已经用了3年之久,从最初的的小白到现在的大白,总有一种要骂娘的冲动,.net这一路走来现在越走越迷茫,不知道微软的重心在哪里,一直发现不了他的亮点所 ...
- poj3261 Milk Patterns 后缀数组求可重叠的k次最长重复子串
题目链接:http://poj.org/problem?id=3261 思路: 后缀数组的很好的一道入门题目 先利用模板求出sa数组和height数组 然后二分答案(即对于可能出现的重复长度进行二分) ...
- 学习笔记:javascript内置对象:数组对象
1.数组对象的创建 1.设置一个长度为0的数组 var myarr=new array(); 2.设置一个长度为n的数组 var myarr=new arr(n); 3.声明一个赋值的指定长度 ...
- [刷题]算法竞赛入门经典 3-1/UVa1585 3-2/UVa1586 3-3/UVa1225
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO(我也是在网上找到的pdf,但不记得是从哪里搜刮到的了,就重新上传了一遍) PS:第一次写博客分享我的代码,不知道我对c ...
- Java7中的ForkJoin并发框架初探(中)——JDK中实现简要分析
原文发表于 2013 年 8 月 28 日 由 三石 根据前文描述的Doug Lea的理论基础,在JDK1.7中已经给出了Fork Join的实现.在Java SE 7的API中,多了ForkJoin ...
- [linux 整理] linux启动过程3
本文介绍linux启动过程的第三步 busybox--------------------> rc init busybox位置即内容 busybox/init/init.c 1.各种设置信号 ...
- FutureTask——另一种闭锁的实现
关于多线程,我们接触对多的,最基础,入门的可能就是实现Runnable接口继承Thead类,因为Java单继承的原因,通常建议是实现Runnable接口.但这种"简单"的线程会带来 ...
- 获取JUnit的执行结果
junit执行之后会有一个结果展示,下面就来看一下怎么获取这些结果并将其存储为一个对象 junit代码如下: package test; import org.junit.After; import ...