垃圾回收机制

在学习这个抽象概念前,老习惯,灵魂二问

什么是?为什么要有?

引言:在程序运行到变量定义时,会在内存空间中存放变量值,然而内存空间是有限的,变量是无限的。

Q:如何在有限的内存里存里存放无限的变量呢?

A:不存在的,但是可以对变量赋值的过程进行优化。

由此诞生了垃圾回收机制

1.什么是垃圾回收机制

垃圾回收机制(简称GC)是python解释器自带的一种机制,专门用来回收不可能访问的变量值所占用的内存空间。

Q:那么什么是垃圾呢?

A:可以用一段代码来解释:

a = 10
#这个过程在我们看来是我们给了a这个变量传了一个值为10
#而在计算机底层是这样的,在定义变量a时,在内存里开辟了一个空间,这个空间用来存放10,变量a和值10存在绑定关系,这种绑定关系叫做引用计数,此时10的引用计数为1。
a = 20
#这个时候我们重新在内存里开辟了一个空间,在里面存放了一个值为20,并将a和10的绑定关系解除,把20和a绑定。这个时候10的引用计数为0,20的引用计数为1,这样在内存里存在了一个无法访问的变量值,但是它会一直占用内存空间,这就是垃圾。

2.为什么要有垃圾回收机制

在程序的运行中,会占用大量的内存空间,时间长了就会存在许多没有用的垃圾占用大量的内存空间,如果不及时清理会造成内存使用殆尽(内存溢出),导致程序崩溃。

3.垃圾回收机制扩展

这时候可能会觉得哪里不对劲,引用计数的变化是在每一个变量定义时都会记录,存在非常大的效率问题。就像你在写作业,一个人写一次老师就检查一次,一个人还好,如果全校每个人的作业写完都是这个老师检查过去,就非常麻烦。

而且,引用计数还存在一个非常致命的缺陷,就是循环引用

# 如下我们定义了两个列表,简称列表1与列表2,变量名l1指向列表1,变量名l2指向列表2
l1=['xxx'] # 列表1被引用一次,列表1的引用计数变为1
l2=['yyy'] # 列表2被引用一次,列表2的引用计数变为1
l1.append(l2) # 把列表2追加到l1中作为第二个元素,列表2的引用计数变为2
l2.append(l1) # 把列表1追加到l2中作为第二个元素,列表1的引用计数变为2 # l1与l2之间有相互引用
# l1 = ['xxx'的内存地址,列表2的内存地址]
# l2 = ['yyy'的内存地址,列表1的内存地址]
l1 ['xxx', ['yyy', [...]]]
l2 ['yyy', ['xxx', [...]]]
l1[1][1][0]
>>>'xxx'
#到这里我们的准备工作结束了,我们可以看一下两个列表的引用计数,l1列表的内容,被l1引用了1次,被l2中第二个元素引用了一次,此时l1列表的内容引用计数为2
del l1# 列表l1的引用计数减少1,现在引用计数为1
del l2# 列表l2的引用计数减少1,现在引用计数为1
#但是此时我们却无法访问l1列表内的内容,本该被当做垃圾删除,但是他的引用计数为1,被l2列表间接引用。这个时候引用计数在这种垃圾身上就失效了。

4.标记清除

标记清除是为了弥补引用计数的缺陷,解决容器对象(list,set,dict...)内循环引用的问题。

在了解这个之前,我们可以更深入的看一下变量定义的过程

x = 10

是在栈区中有变量名x,还有x和10的关联关系,在堆区里存放着值10

当我们执行x=y时,内存中栈区和堆区的变化:

Q:标记清除是和引用计数一起工作的吗?又是怎么工作的呢?

A:标记清除是当内存即将被应用程序占满时,会把整个程序停下来,开始执行标记清除,此时分为两步:

第一步:标记

​ 标记的过程其实就是,遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活的对象,其余的均为非存活对象,应该被清除。

第二步:

​ 清除 清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。

这里再回到刚刚标记清除里的代码,循环引用时的情况,我们del l1和del l2时会在栈区里把l1和堆区内的l1的内容的元素清除绑定关系,这个时候只有在堆区内两个列表的元素在互相引用,此时就被标记了。然后所有类似的没有和栈区内的变量名有直接引用关系的都会被清除!

5.分代回收

标记清除解决了引用计数在循环引用上的缺陷,而分代回收就是为了解决引用计数的第二个缺陷,效率问题。

分代:可以做个比喻,在一个班里有40个学生,每天教一份作业,每次都检查就会很麻烦,所以我们可以在多次检查后,把这40个学生分为几部分:

第一部分:好学生,每次都交,就一周检查一次把

第二部分:良好的学生,偶尔不交,就三天检查一次把

第三部分:差生,总是不交,每次都得检查

在这样区分后,每次检查作业的效率就提高了。在程序中,每一部分就分为每一代,根据每一代的性质不同,对他们的扫描频率就不同。

即便这样,也存在缺陷,比如一个学生刚当上好学生,他就不交作业了,但是我们一周才能查出来。在程序中就是一个被放入最高代的变量,他刚进去变量绑定关系就解除了,但是这一代的扫描频率很低,很久才能把它查出来。

day05 垃圾回收机制(超小白讲解)的更多相关文章

  1. 通俗易懂.NET GC垃圾回收机制(适用于小白面试,大牛勿喷)

    情景:你接到xx公司面试邀请,你怀着激动忐忑的心坐在对方公司会议室,想着等会的技术面试.技术总监此时走来,与你简单交谈后.... 技术:你对GC垃圾回收机制了解的怎么样? 你:还行,有简单了解过. 技 ...

  2. 超详细的node/v8/js垃圾回收机制

    前言 垃圾回收器是一把十足的双刃剑.其好处是可以大幅简化程序的内存管理代码,因为内存管理无需程序员来操作,由此也减少了(但没有根除)长时间运转的程序的内存泄漏.对于某些程序员来说,它甚至能够提升代码的 ...

  3. Python垃圾回收机制--完美讲解!

    转自: http://www.jianshu.com/p/1e375fb40506 先来个概述,第二部分的画述才是厉害的. Garbage collection(GC) 现在的高级语言如java,c# ...

  4. 通过实例详细讲解PHP垃圾回收机制

    PHP垃圾回收机制:1. PHP可以自动进行内存管理,清除不需要的对象,主要使用了引用计数2. 在zval结构体中定义了ref_count和is_ref , ref_count是引用计数 ,标识此zv ...

  5. day05基本运算符,格式化输出,垃圾回收机制

    内容大纲:1.垃圾回收机制详解(了解) 引用计数 标记清除 分代回收 2.与用户交互 接收用户输入 # python3中 input # python2.7(了解) input raw_input 格 ...

  6. Java Garbage Collection基础详解------Java 垃圾回收机制技术详解

    最近还是在找工作,在面试某移动互联网公司之前认为自己对Java的GC机制已经相当了解,其他面试官问的时候也不存在问题,直到那天该公司一个做搜索的面试官问了我GC的问题,具体就是:老年代使用的是哪中垃圾 ...

  7. 成为Java GC专家(3)—如何优化Java垃圾回收机制

    为什么需要优化GC 或者说的更确切一些,对于基于Java的服务,是否有必要优化GC?应该说,对于所有的基于Java的服务,并不总是需要进行GC优化,但前提是所运行的基于Java的系统,包含了如下参数或 ...

  8. CMS垃圾回收机制

    详解CMS垃圾回收机制   原创不易,未经允许,不得转载~~~ 什么是CMS? Concurrent Mark Sweep. 看名字就知道,CMS是一款并发.使用标记-清除算法的gc. CMS是针对老 ...

  9. 要想学好Java编程,构造器、方法重载、this关键字、垃圾回收机制,这4关一定要过!

    有人说,你应该关注时事.财经,甚至流行的电影.电视剧,才有可能趁着热点写出爆文:有人说,你别再写“无聊”的技术文了,因为程序员的圈子真的很小,即便是像鸿洋那样的招牌大牛,文章是那么的干货,浏览量有多少 ...

随机推荐

  1. 关于thinkphp5下URL附加参数,无法获取到(?参数)

    nginx 配置问题: 修改配置后:

  2. Vue —— 精讲 VueRouter(1)

    最近被Boos调去给新人做培训去了,目前把自己整理的一些东西分享出来,希望对大家有所帮助 本章节为VueRouter前端 路由的章节部分 大纲 一.基本概念 路由就是通过网络把讯息从源地址传输到目的地 ...

  3. PAI-AutoLearning 图像分类使用教程

    概述 PAI AutoLearning(简称PAI AL)自动学习支持在线标注.自动模型训练.超参优化以及模型评估.在平台上只需准备少量标注数据,设置训练时长即可得到深度优化的模型.同时自动学习PAI ...

  4. 当小程序的flex布局遇到button时,justify-content不起作用的原因及解决方案

    当小程序的flex布局遇到button时 发现justify-content不起作用,无论怎么设置都是space-around的效果. 经过排查,发现原因是小程序button中的默认样式中的margi ...

  5. 基于docker-compose搭建gitlab

    安装及配置 修改docker-compose文件 vim docker-compose.yml gitlab: image: 'gitlab/gitlab-ce:latest' restart: al ...

  6. cb23a_c++_标准模板库STL_set_multiset_关联容器

    cb23a_c++_标准模板库STL_set_multiset_关联容器 set(集)数据不能重复.multiset(多集)可以重复.操作数据速度快,数据自动排序.红黑树(数据结构)红黑树-二叉树基本 ...

  7. Spring Data 教程 - Redis

    1. Redis简介 Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value ...

  8. [转]IP地址和MAV地址——区别和联系

    [转载]http://wenda.tianya.cn/question/27f9476d1e86f6b6 一.IP地址  对于IP地址,相信大家都很熟悉,即指使用TCP/IP协议指定给主机的32位地址 ...

  9. Mysql Workbench中EER Diagram逆向生成表

    选择链接 选择需要生成的表

  10. 想学好Python,你必须了解Python中的35个关键词

    每种编程语言都会有一些特殊的单词,称为关键词.对待关键词的基本要求是,你在命名的时候要避免与之重复.本文将介绍一下Python中的关键词.关键词不是内置函数或者内置对象类型,虽然在命名的时候同样也最好 ...