啥,内存也会泄露?漏了咋补?我的内存会不会越漏越小?咋一听到内存泄漏,本喵的脑子蹦出无数想法,所以到底啥是内存泄漏!

一、垃圾回收机制(GC)机制

在理解内存泄漏之前,需要补充一个知识,即GC机制(也就是垃圾回收机制)。

1、工作原理

  我们知道,电脑的内存空间有限,而我们在编写代码时,会不停的产生变量,这没有问题,但是一旦我们将变量值与变量名解绑,那么变量值就无法被访问,这一部分内存空间也就被占用,形成我们说的“垃圾”。为了节省内存空间,提高效率,python官方在程序中内置了GC机制,他的核心原理如下:

  • 引用计数

  GC机制中引入了引用计数,如果某个变量被引用,引用计数+1,如果解绑一次,引用计数-1,若果引用计数变为0,那么值就会被清除,回收内存空间。

  • 分代回收

  当变量值较少的时候,前面扫描内存还可以,但是变量一直增多,每一次扫描费时费力,有什么办法优化呢?于是有了分代回收。

  当某个变量每一次扫描引用计数都不为0,那么就会被打上“不错呦”标签,GC机制就会减少扫描这个变量的次数,以此提高程序运行效率

  分代回收也有缺点,如果恰好有一个变量刚被打上标签,引用计数就变为0了,导致个别变量无法及时清理,但是瑕不掩瑜

  • 标记/清除原理

  下面就是本文开头提到的内存泄漏问题了,先看一段代码:

>>> l1 = [111]>>> l2 = [222]>>> l1.append(l2)>>> l2.append(l1)>>> l1[111, [222, [...]]]>>> l2[222, [111, [...]]]>>> del l1>>> del l2

  这一段代码看起来是不是怪怪的,这涉及到循环引用:

首先我们来看建立列表L1,L2的过程

在内存当中,变量的存取是在栈区和堆区间进行的,栈区存储的是变量名和他指定的变量值的内存地址,堆区中,会开辟出一个内存空间存储变量值,通过内存地址标识,通过之前我们学习的变量赋值将变量名和变量值绑定起来

直接从栈区到达堆区变量值的引用叫做直接引用,如:L1[0],

不是直接从栈区到堆区,而是通过其他途径引用的,叫间接引用,如L1[1][0]

之后我们通过append方法将L1和L2的内存地址分别加到对方的列表中去,于是我们可以看到,在堆区,L1和L2分别有一条路径达到对方,这就是循环引用。

最后一步,我们将L1和L2解除绑定,这时有两个结果:

  • 栈区中没有一条路径可以到达之前的两个列表,意味着我们无法访问
  • 二是在堆区中仍然存在至少1条路径指向两个列表,这意味着引用计数不为0,这一部分内存无法回收

这就是内存泄漏,我们无法利用两个列表,也无法通过引用计数删除。好在这个问题也被python开发者想到了,设计了标记/清除的方法

GC机制会扫描堆区,对那些无法从栈区访问到的(没有直接引用,也没有间接引用)内存空间进行标记,判断存在内存泄漏后,将这些变量值删除,释放内存空间。

(理论解释太难了, 有什么错误希望各位大佬指出,本喵及时改正,举爪!)

最新文章

  1. 入手了[云梯的VPN]--水文
  2. C语言中一个替换 strcpy的极好的方法
  3. 国内市场上 Android 手机屏幕分辨率的比例情况如何?
  4. 关于 hangfire 初始化工作机制
  5. 创建PO/SO
  6. 在Ubuntu Linux下怎样安装QQ
  7. iOS_25彩票_幸运转盘
  8. caffe层解读系列-softmax_loss
  9. C语言第一周作业
  10. Sublime Text 3 安装简记
  11. element-ui <el-select> + <el-option> 回显格式为中文 传值格式为对应value
  12. 神经网络和误差逆传播算法(BP)
  13. window配置 mysql 详细步骤
  14. 爬取微博的数据时别人用的是FM.view方法传递html标签那么jsoup怎么解析呢
  15. Dig命令解析结果
  16. Python的数据类型1数值和字符串
  17. AJAX异步实现简单的瀑布流
  18. MOSS 2013研究系列---列表的资源限制
  19. 一句话说说java设计模式
  20. [洛谷3041]视频游戏的连击Video Game Combos

热门文章

  1. js Memory Management
  2. holy shit StackOverflow
  3. auto responsive rem
  4. svg 矩阵转换
  5. 教你玩转CSS 居中
  6. java中synchronized与Lock的异同
  7. C++使用libcurl进行http通讯
  8. python进阶(1)Lambda表达式
  9. MYSQL安全模式"sql_safe_updates"设置update和delete不带where的操作限制
  10. 《进击吧!Blazor!》第一章 5.组件开发