引用

先上个示例:

  1. >>> val = [1]
  2. >>> val[0] = val
  3. >>> val
  4. [[...]]

上述代码使val中包含自身,而产生了无限递归。上述示例表明Python中的变量名为引用类型,赋值只是使得左值指向与右值相同的内存对象。

is运算符可以判断两个引用是否指向了同一个对象,而==运算符判断两个引用指向的值是否相等而不关心指向什么对象。

对引用不了解的朋友,可以把Python引用与C/C++中的void *类比,不过因为垃圾回收机制Python引用无需担心内存泄漏的问题。

复制

上面的示例表明赋值无法为对象建立副本,python中的copy模块提供了copydeepccopy建立副本。

示例:

  1. >>> import copy
  2. >>> a = [[1, 2, 3], [4, 5, 6]]
  3. >>> b = a
  4. >>> c = copy.copy(a)
  5. >>> d = copy.deepcopy(a)
  6. >>> a.append(7)
  7. >>> a[1][2] = 0
  8. >>> a
  9. [[1, 2, 3], [4, 5, 0], 7]
  10. >>> b
  11. [[1, 2, 3], [4, 5, 0], 7]
  12. >>> c
  13. [[1, 2, 3], [4, 5, 0]]
  14. >>> d
  15. [[1, 2, 3], [4, 5, 6]]

浅复制copy.copy只复制父引用指向的对象,其子引用仍指向原来的内存对象,而深复制copy.deepcopy则会复制所有引用指向的对象。deepcopy 本质上是递归 copy。

示例中的副本c,d父对象是a的副本所以a.append方法对它们没有影响。

但是copy.copy创建的副本c中的元素仍指向与a相同的内存对象,而deepcopy创建的d则指向了自己的元素。

tuple和frozenset之类的容器只是保证其中引用指向不变,但是引用指向的内存对象仍然是可变的。容器的切片对象的机制为浅复制。

x = x + y,必须创建新的临时变量然后进行浅复制,性能较差。

x += y,无需新建临时对象,只在内存块末尾增加元素,性能较好。

参数传递

Python中的参数传递采用浅复制的值传递。

示例:

  1. >>> def swap(a,b):
  2. ... b,a=a,b
  3. ...
  4. >>> a = 1
  5. >>> b = 2
  6. >>> swap(1,2)
  7. >>> a
  8. 1
  9. >>> b
  10. 2

上述示例证明,Python参数传递是采用值传递的方式。

示例2:

  1. >>> def fun(a):
  2. ... a[0] = 2
  3. ...
  4. >>> a = [1]
  5. >>> fun(a)
  6. >>> a
  7. [2]

这个示例则证明采用浅复制的方法进行传递。

垃圾回收

Python中的垃圾回收是以引用计数为主,标记-清除和分代收集为辅。

一组对象互相引用的情况称为循环引用(交叉引用),若出现这种情况引用计数将无法正确的回收垃圾。,可以包含其他对象引用的容器对象(如list, dict, set,甚至class)都可能产生循环引用。

标记 - 清除

“标记-清除”法是为了解决循环引用问题。

垃圾标记时,先将集合中对象的引用计数复制一份副本(以免在操作过程中破坏真实的引用计数值),然后操作这个副本,遍历对象集合,将被引用对象的引用计数副本值减1。

根据引用计数副本值是否为0将集合内的对象分成两类,reachable和unreachable,其中unreachable是可以被回收的对象。

分代回收

分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。

弱引用

弱引用是避免循环引用的一种方法,弱引用不记录引用计数。当一个对象只有弱引用时可能被垃圾回收器回收。

weakref.ref(obj,[callable])用于建立一个指向obj的弱引用,当对象被回收前callable可选参数指定的函数将被执行以进行清理工作。

Python引用的那些坑

使用GC分析Python垃圾回收机制

CPython源代码分析垃圾回收机制

Python引用复制,参数传递,弱引用与垃圾回收的更多相关文章

  1. C++引用计数设计与分析(解决垃圾回收问题)

    1.引言 上一篇博文讲到https://www.cnblogs.com/zhaoyixiang/p/12116203.html 我们了解到我们在浅拷贝时对带指针的对象进行拷贝会出现内存泄漏,那C++是 ...

  2. Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))

    因为之前项目同事使用了图片三级缓存,今天整理项目的时候发现同事还是使用了软引用(SoftRefrerence)和弱引用(WeakReference),来管理在内存中的缓存.看到这个我就感觉不对了.脑海 ...

  3. Python可变与不可变类型及垃圾回收机制

    1. 可变与不可变类型 1.1  可变类型 在id不变的情况下,value可以改变,则称之为可变类型.列表.字典与集合是可变的. l1 = [,,,,] print(id(l1)) l1[] = #改 ...

  4. 强引用strong和弱引用weak的定义

    1.强引用表示从属关系,引用对象拥有被引用的对象.弱引用则暗示引用对象不拥有被引用的对象.一个对象的寿命是由它被强引用多少次来决定的.只要对象还存在强引用,就不会释放该对象. 注意:但是对象之间的引用 ...

  5. 【python测试开发栈】—python内存管理机制(二)—垃圾回收

    在上一篇文章中(python 内存管理机制-引用计数)中,我们介绍了python内存管理机制中的引用计数,python正是通过它来有效的管理内存.今天来介绍python的垃圾回收,其主要策略是引用计数 ...

  6. 强引用,弱引用,4种Java引用浅解(涉及jvm垃圾回收)

    http://www.jb51.net/article/49085.htm http://www.jb51.net/article/49085.htm

  7. 三、python对字符串和集合的内存垃圾回收机制

    变量声明: name1 = "andy" name2 = name1   这个时候我把name1的值给改成了“tom”,问现在name2的值是什么?为什么? 答:andy,因为你把 ...

  8. JVM 垃圾回收算法和垃圾回收器

    JVM 垃圾回收算法和垃圾回收器. 一.垃圾回收的区域 栈:栈中的生命周期是跟随线程,所以一般不需要关注. 堆:堆中的对象是垃圾回收的重点. 方法区:这一块也会发生垃圾回收,不过这块的效率比较低,一般 ...

  9. 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用

    垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...

  10. Java中的引用类型(强引用、弱引用)和垃圾回收

    Java中的引用类型和垃圾回收 强引用Strong References 强引用是最常见的引用: 比如: StringBuffer buffer = new StringBuffer(); 创建了一个 ...

随机推荐

  1. python 实现九型人格测试小程序

    用python实现九型人格测试,并把测试结果绘制成饼图,实现代码如下: # @Description: 九型人格 import xlrd, matplotlib.pyplot as plt data ...

  2. 在centos7升级jenkins

    找到jenkins的位置 使用下面的命令 ps -aux | grep jenkins enkins    5954  7.9 22.5 2695800 421088 ?      Ssl  20:5 ...

  3. Buck工作原理分析,连续模式,断续模式

    Part01:Buck电路工作原理: 图1-1 Buck电路拓扑结构 Buck电路的拓扑结构如图1-1所示: (1) input接输入电源,既直流电动势: (2) IGBT1为开关管,可以选择以全控型 ...

  4. jzoj5888

    tj:暴力連邊會tle 我們發現所有邊的邊權最大值不超過100000,這意味著可以設計和邊權有關的算法,假設現在邊權不相同 枚舉一個現在的邊權i,代表gcd為i,設連的2個點權值為a1∗ia1*ia1 ...

  5. C/C++ 语言 Hello world

    #include <stdio.h> void main() { int x,i; ; scanf("%d",&x); if(x>y) printf(&q ...

  6. FunDA(8)- Static Source:保证资源使用安全 - Resource Safety

    我们在前面用了许多章节来讨论如何把数据从后台数据库中搬到内存,然后进行逐行操作运算.我们选定的解决方案是把后台数据转换成内存中的数据流.无论在打开数据库表或从数据库读取数据等环节都涉及到对数据库表这项 ...

  7. Exploit之初识Linux下缓冲区溢出

    本文的目的不是为了介绍如何进行恶意的破坏性活动,而是为了教会你如何去防御此类破坏性活动,以帮助你扩大知识范围,完善自己的技能,如有读者运用本文所学技术从事破坏性活动,本人概不负责. 0×01 前言 1 ...

  8. Lucence工作原理

    lucence 是一个高性能的java全文检索工具包,他使用倒排序文件索引结构,改结构和相应的生成算法如下: 一.设有两篇文章1和2      文章1的内容为:Tom lives in guangzh ...

  9. js插件实现点击复制内容到粘贴板,兼容IE8

    先来看下本次需要导入的文件: 第一个是jquery.js,这个不多说: 第二个是jquery.zclip.js,第三个是zeroClipboard.swf ,这两个文件的下载链接:http://www ...

  10. 希尔排序的理解和实现(Java)

    希尔排序原理 希尔排序(shell sort)这个排序方法又称为缩小增量排序,是1959年D·L·Shell提出来的. 该方法的基本思想是:设待排序元素序列有n个元素,首先取一个整数increment ...