day05 垃圾回收机制(超小白讲解)
垃圾回收机制
在学习这个抽象概念前,老习惯,灵魂二问
什么是?为什么要有?
引言:在程序运行到变量定义时,会在内存空间中存放变量值,然而内存空间是有限的,变量是无限的。
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 垃圾回收机制(超小白讲解)的更多相关文章
- 通俗易懂.NET GC垃圾回收机制(适用于小白面试,大牛勿喷)
情景:你接到xx公司面试邀请,你怀着激动忐忑的心坐在对方公司会议室,想着等会的技术面试.技术总监此时走来,与你简单交谈后.... 技术:你对GC垃圾回收机制了解的怎么样? 你:还行,有简单了解过. 技 ...
- 超详细的node/v8/js垃圾回收机制
前言 垃圾回收器是一把十足的双刃剑.其好处是可以大幅简化程序的内存管理代码,因为内存管理无需程序员来操作,由此也减少了(但没有根除)长时间运转的程序的内存泄漏.对于某些程序员来说,它甚至能够提升代码的 ...
- Python垃圾回收机制--完美讲解!
转自: http://www.jianshu.com/p/1e375fb40506 先来个概述,第二部分的画述才是厉害的. Garbage collection(GC) 现在的高级语言如java,c# ...
- 通过实例详细讲解PHP垃圾回收机制
PHP垃圾回收机制:1. PHP可以自动进行内存管理,清除不需要的对象,主要使用了引用计数2. 在zval结构体中定义了ref_count和is_ref , ref_count是引用计数 ,标识此zv ...
- day05基本运算符,格式化输出,垃圾回收机制
内容大纲:1.垃圾回收机制详解(了解) 引用计数 标记清除 分代回收 2.与用户交互 接收用户输入 # python3中 input # python2.7(了解) input raw_input 格 ...
- Java Garbage Collection基础详解------Java 垃圾回收机制技术详解
最近还是在找工作,在面试某移动互联网公司之前认为自己对Java的GC机制已经相当了解,其他面试官问的时候也不存在问题,直到那天该公司一个做搜索的面试官问了我GC的问题,具体就是:老年代使用的是哪中垃圾 ...
- 成为Java GC专家(3)—如何优化Java垃圾回收机制
为什么需要优化GC 或者说的更确切一些,对于基于Java的服务,是否有必要优化GC?应该说,对于所有的基于Java的服务,并不总是需要进行GC优化,但前提是所运行的基于Java的系统,包含了如下参数或 ...
- CMS垃圾回收机制
详解CMS垃圾回收机制 原创不易,未经允许,不得转载~~~ 什么是CMS? Concurrent Mark Sweep. 看名字就知道,CMS是一款并发.使用标记-清除算法的gc. CMS是针对老 ...
- 要想学好Java编程,构造器、方法重载、this关键字、垃圾回收机制,这4关一定要过!
有人说,你应该关注时事.财经,甚至流行的电影.电视剧,才有可能趁着热点写出爆文:有人说,你别再写“无聊”的技术文了,因为程序员的圈子真的很小,即便是像鸿洋那样的招牌大牛,文章是那么的干货,浏览量有多少 ...
随机推荐
- DBusConnection for c
dbus的C API D-Bus 1.13.10 目录 dbus的C API Detailed Description Typedef Documentation ◆ DBusAddTimeoutFu ...
- 使用FFT进行频谱分析
import numpy as np import matplotlib.pyplot as plt from scipy.fftpack import fft fs=100 #采样频率 N=128 ...
- ArchLinux——使用WINE-TIM头像异常解决办法
ArchLinux--使用WINE-TIM头像异常解决办法 当使用WINE-TIM头像图片加载异常时,执行以下命令 sudo sysctl -w net.ipv6.conf.all.disable_i ...
- <VCC笔记> 关于Assertion
这篇博客开始介绍VCC的用法,先用简单的例子介绍VCC的基本语法,当然面对更复杂的程序时,VCC也是将他简化然后分析的. 1.Assertion #include <vcc.h> int ...
- AsyncOperation和SceneManager.LoadSceneAsync协同加载场景
这篇属于杂记,用于记录不甚理解的AsyncOperation AsyncOperation: //加载进度条 public Silder silder; 加载场景 public void LoginG ...
- Machine Learning Note
[Andrew Ng NIPS2016演讲]<Nuts and Bolts of Applying Deep Learning (Andrew Ng) 中文详解:https://mp.weixi ...
- 05、MyBatis 缓存
1.MyBatis缓存 MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制.缓存可以极大的提升查询效率. 1).一级缓存 public Employee getEmpById( ...
- SpringCloud与Eureka,Feign,Ribbon,Hystrix,Zuul核心组件间的关系
Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从而知道其他服务在 ...
- hashcode和==
public class Main { public static void main(String[] args) { Object o=new Object(); System.out.print ...
- 面试题40:最小的 k 个数
import java.util.Arrays; /** * Created by clearbug on 2018/2/26. * * 面试题40:最小的 k 个数 * * 注意:因为前两天在陌陌面 ...