一.垃圾回收机制

垃圾回收机制是自动帮助我们管理内存,清理垃圾的一种工具

一.堆区与栈区

​在定义变量时,变量名与变量值都是需要存储的,分别对应内存中的两块区域:堆区与栈区。

1、变量名与值内存地址的关联关系存放于栈区

2、变量值存放于堆区,内存管理回收的则是堆区的内容,

二.直接引用与间接引用

​1.直接引用指的是从栈区出发直接引用到的内存地址。

​2.间接引用指的是从栈区出发引用到堆区后,再通过进一步引用才能到达的内存地址。

1.引用计数

  1. 当一个对象的引用被创建或者复制时,对象的引用计数加1
  2. 当一个对象的引用被销毁时,对象的引用计数减1
  3. 当对象的引用计数减少为0时,就意味着对象已经没有被任何人使用了,可以将其所占用的内存释放了。
  4. 优点:
  5. 简单、直观
  6. 实时性,只要没有了引用就释放资源。
  7. 缺点:
  8. 维护引用计数需要消耗一定的资源
  9. 循环应用时,无法回收。也正是因为这个原因,才需要通过标记-清理和分代收集机制来辅助引用计数机制。

变量值被关联次数的增加或减少,都会引发引用计数机制的执行(增加或减少值的引用计数),这存在明显的效率问题。

如果说执行效率还仅仅是引用计数机制的一个软肋的话,那么很不幸,引用计数机制还存在着一个致命的弱点,即循环引用(也称交叉引用)

  1. 如下我们定义了两个列表,简称列表1与列表2,变量名l1指向列表1,变量名l2指向列表2
  2. >>> l1=['xxx'] # 列表1被引用一次,列表1的引用计数变为1
  3. >>> l2=['yyy'] # 列表2被引用一次,列表2的引用计数变为1
  4. >>> l1.append(l2) # 把列表2追加到l1中作为第二个元素,列表2的引用计数变为2
  5. >>> l2.append(l1) # 把列表1追加到l2中作为第二个元素,列表1的引用计数变为2
  6. l1l2之间有相互引用
  7. l1 = ['xxx'的内存地址,列表2的内存地址]
  8. l2 = ['yyy'的内存地址,列表1的内存地址]
  9. >>> l1
  10. ['xxx', ['yyy', [...]]]
  11. >>> l2
  12. ['yyy', ['xxx', [...]]]
  13. >>> l1[1][1][0]
  14. 'xxx'

循环引用会导致:值不再被任何名字关联,但是值的引用计数并不会为0,应该被回收但不能被回收,什么意思呢?试想一下,请看如下操作

  1. >>> del l1 # 列表1的引用计数减1,列表1的引用计数变为1
  2. >>> del l2 # 列表2的引用计数减1,列表2的引用计数变为1

此时,只剩下列表1与列表2之间的相互引用,两个列表的引用计数均不为0,但两个列表不再被任何其他对象关联,没有任何人可以再引用到它们,所以它俩占用内存空间应该被回收,但由于相互引用的存在,每一个对象的引用计数都不为0,因此这些对象所占用的内存永远不会被释放,所以循环引用是致命的,这与手动进行内存管理所产生的内存泄露毫无区别。 所以Python引入了“标记-清除” 与“分代回收”来分别解决引用计数的循环引用与效率低的问题

2.标记-清除(用来解决循环引用带来的内存泄露问题)

  1. “标记-清除”不改动真实的引用计数,而是将
  2. 集合中对象的引用计数复制一份副本,改动该对象引用的副本。对于副
  3. 本做任何的改动,都不会影响到对象生命走起的维护。

3.分代回收(用来降低引用计数的扫描频率,提升垃圾回收的效率)

  1. 将系统中的所有内存块根据其存活时间划分为不同的集合,
  2. 每一个集合就成为一个“代”,垃圾收集的频率随着“代”的存活时间的增大而减小。
  3. 也就是说,活得越长的对象,就越不可能是垃圾,就应该减少对它的垃圾收集频率。
  4. 那么如何来衡量这个存活时间:通常是利用几次垃圾收集动作来衡量,
  5. 如果一个对象经过的垃圾收集次数越多,可以得出:该对象存活时间就越长。

总结

  1. 1、标记
  2. 通俗地讲就是:
  3. 栈区相当于“根”,凡是从根出发可以访达(直接或间接引用)的,都称之为“有根之人”,有根之人当活,无根之人当死。
  4. 具体地:标记的过程其实就是,遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活的对象,其余的均为非存活对象,应该被清除。
  5. 2、清除
  6. 清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。

二.驻留机制

  1. 对于短字符串,将其赋值给多个不同的对象时,内存中只有一个副本,多个对象共享该副
  2. 本。长字符串不遵守驻留机制。
  3. 驻留适用范围: 由数字,字符和下划线(_)组成的python标识符以及整数[-5,256]。

python基础扩展的更多相关文章

  1. python基础扩展(二)

    python基础扩展(二) 常用操作 1.startswith(以什么开始) endswith(y)什么结束 s='taiWanw39dd' print(s.startswith('t')) #意思是 ...

  2. Python基础+Pythonweb+Python扩展+Python选修四大专题 超强麦子学院Python35G视频教程

    [保持在百度网盘中的, 可以在观看,嘿嘿 内容有点多,要想下载, 回复后就可以查看下载地址,资源收集不易,请好好珍惜] 下载地址:http://www.fu83.cc/ 感觉文章好,可以小手一抖 -- ...

  3. 【转】Python基础-封装与扩展、静态方法和类方法

    [转]Python基础-封装与扩展.静态方法和类方法 一.封装与扩展 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码:而外部使用者只知道一个接口(函数),只要接口(函数 ...

  4. Python小白的发展之路之Python基础(一)

    Python基础部分1: 1.Python简介 2.Python 2 or 3,两者的主要区别 3.Python解释器 4.安装Python 5.第一个Python程序 Hello World 6.P ...

  5. python基础之文件读写

    python基础之文件读写 本节内容 os模块中文件以及目录的一些方法 文件的操作 目录的操作 1.os模块中文件以及目录的一些方法 python操作文件以及目录可以使用os模块的一些方法如下: 得到 ...

  6. python基础之循环结构以及列表

    python基础之编译器选择,循环结构,列表 本节内容 python IDE的选择 字符串的格式化输出 数据类型 循环结构 列表 简单购物车的编写 1.python IDE的选择 IDE的全称叫做集成 ...

  7. Python基础-字符编码与转码

    ***了解计算机的底层原理*** Python全栈开发之Python基础-字符编码与转码 需知: 1.在python2默认编码是ASCII, python3里默认是utf-8 2.unicode 分为 ...

  8. Python之路【第二篇】:Python基础

    参考链接:老师 BLOG : http://www.cnblogs.com/wupeiqi/articles/4906230.html 入门拾遗 一.作用域 只要变量在内存中就能被调用!但是(函数的栈 ...

  9. python基础——多重继承

    python基础——多重继承 继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能. 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗: Bat ...

随机推荐

  1. HDU-2841 Visible Trees(莫比乌斯反演)

    Visible Trees 传送门 解题思路: 实际上的答案就是1~n与1~m之间互质的数的对数,写出式子就是 \(ans=\sum^{n}_{i=1}\sum^{m}_{j=1}[gcd(i,j)= ...

  2. EXCEL的VBA(宏)编程

    EXCEL的VBA编程 杨康需要我完成的需求 第一列是名称 第二列是甲方账户 第三列是甲方金额 第四列是乙方账户 第五列是乙方金额 第六列是true或false 第七列备注 需求 开始时数据对齐的,如 ...

  3. Stopping service [Tomcat] Disconnected from the target VM, address:XXXXXX解决方案

    原文出处:https://blog.csdn.net/u013294097/article/details/90677049 Stopping service [Tomcat] Disconnecte ...

  4. django3.x版本不支持MySQL5.x版本

    其实django2.0版本已经不再支持MySQL5.x的了,最开始是安装了MySQL5.1,在学习django 的时候,django版本为3.0,在执行`python manage.py migrat ...

  5. tmobst5

    (单选题)SQL语言又称为() A)结构化定义语言 B)结构化控制语言 C)结构化查询语言 D)结构化操纵语言 2.(单选题)只有满足联接条件的记录才包含在查询结果中,这种联接为( ) A)左联接 B ...

  6. 使用脚本+kafka自带命令行工具 统计数据写入kafka速率

    思路 每隔一段时间(比如说10秒)统计一次某topic的所有partition的最大offset值之和,这便是该topic的message总数. 然后除以间隔时间就可以粗略但方便得出 某topic的数 ...

  7. P4174 [NOI2006]最大获利 (最大权闭合子图)

    P4174 [NOI2006]最大获利 (最大权闭合子图) 题目链接 题意 建\(i\)站台需要\(p_i\)的花费,当\(A_i,B_i\)都建立时获得\(C_i\)的利润,求最大的利润 思路 最大 ...

  8. JAVA ReentrantLock的使用

    源码如下 对比synchronized,synchronized使用时会显示的指定一个对象(方法为调用对象,代码块会需要对象作为参数),来获取一个对象的独占锁 而ReentrantLock可能就是使用 ...

  9. MongoDB 复本集搭建

    复制集的特点   数据一致性 主是唯一的,但不是固定的  没有MySQL那样的双主结构 大多数原则,集群存活节点小于等于二分之一时集群不可写,只可读. 是否能选举出新的主节点,是由当前复制集成员存活量 ...

  10. centos7利用系统镜像修复grub

    1 故障描述 由于错误操作,导致grub配置文件失效,系统开机后一直卡在下面的画面. 2 解决办法 这时候,就要利用系统镜像光盘,进入修复模式,然后按下面图示操作 进入镜像的shell环境,如下图所示 ...