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

一、垃圾回收机制(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机制会扫描堆区,对那些无法从栈区访问到的(没有直接引用,也没有间接引用)内存空间进行标记,判断存在内存泄漏后,将这些变量值删除,释放内存空间。

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

python那些需要知道的事儿——内存泄漏的更多相关文章

  1. python 内存泄漏调试

    Python应用程序内存泄漏的调试 Quake Lee quakelee@geekcn.org 新浪网技术(中国)有限公司 Sina Research & Development Python ...

  2. <转>Python的内存泄漏及gc模块的使用分析

    一般来说在 Python 中,为了解决内存泄漏问题,采用了对象引用计数,并基于引用计数实现自动垃圾回收.由于Python 有了自动垃圾回收功能,就造成了不少初学者误认为自己从此过上了好日子,不必再受内 ...

  3. 一次python 内存泄漏解决过程

    最近工作中慢慢开始用python协程相关的东西,所以用到了一些相关模块,如aiohttp, aiomysql, aioredis等,用的过程中也碰到的很多问题,这里整理了一次内存泄漏的问题 通常我们写 ...

  4. 【原创】python内存泄漏以及python flask框架莫名coredump

    1.python内存泄漏 今天在看服务器上的进程时,用top查的时候,发现一个一直跑的脚本程序内存竟然达到了1.6G,这个脚本我有印象,一开始仅占用20M左右,显然是内存泄漏了. 用gc和objgra ...

  5. Python之内存泄漏和内存溢出

    预习知识:python之MRO和垃圾回收机制 一.内存泄漏 像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题.对于一个用 python 实现的,长期运行的后台 ...

  6. 填坑总结:python内存泄漏排查小技巧

    摘要:最近服务遇到了内存泄漏问题,运维同学紧急呼叫解决,于是在解决问题之余也系统记录了下内存泄漏问题的常见解决思路. 本文分享自华为云社区<python内存泄漏排查小技巧>,作者:luti ...

  7. python内存泄漏

    记录: 一个脚本在连续运行后,使用内存越来越大,在循环后手动添加gc.collect()没有作用. 尝试方法: 去除所有函数中当作参数传入的全局变量 使用全局redis对象,不再当作参数传入 循环末尾 ...

  8. python中循环引用导致内存泄漏小案例

    首先定义一个Person类和一个Dog类,然后分别实例化对象p和d,给p对象添加一个pet属性 给d对象添加一个master属性此时Person和Dog的应用计数都为2,当del p 和del d后P ...

  9. 精华阅读第 13 期 |常见的八种导致 APP 内存泄漏的问题

    本期是移动开发精英俱乐部的第13期文章,都是以技术为主,所以这里就不过多的进行赘述了,我们直接看干货内容吧!本文系ITOM管理平台OneAPM整理. 实际项目中的MVVM(积木)模式–序章 导读:开篇 ...

随机推荐

  1. 动态规划算法 All In One

    动态规划算法 All In One dynamic programming leetcode https://leetcode.com/tag/dynamic-programming/ https:/ ...

  2. pub package all in one

    pub package all in one best practice The pubspec file https://dart.dev/tools/pub/pubspec demo name: ...

  3. autocode & API

    autocode & API https://autocode.com/app/ https://autocode.com/lib/ api-service https://dashboard ...

  4. 电信悦 me 智能网关

    电信悦 me 智能网关 悦 me 智能网关 Q1:什么是电信悦 me 智能网关? 悦me网关是智慧家庭的核心终端,作为"光猫+智能路由器"的集合体, 采用了全新的硬件.外观及智能操 ...

  5. NGK Global英国路演落下帷幕,区块链赋能大数据取得新突破

    NGK全球巡回路演于7月25日在英国圆满举行,此次路演是由NGK英国社区主办,旨在探讨当前大数据爆炸的形式下,区块链如何赋能,解决行业痛点.会上,行业精英.区块链爱好者.各实体产业代表以及科技人员纷纷 ...

  6. Masterboxan INC是你靠近财富的最佳选择

    Masterboxan INC万事达资产管理有限公司(公司编号:20151264097)是一家国际性资产管理公司,主要提供外汇.证券.投资管理和财富管理等金融服务,其在投资方面一直倡导组合型投资构建稳 ...

  7. sklearn中的pipeline的创建与访问

    前期博文提到管道(pipeline)在机器学习实践中的重要性以及必要性,本文则递进一步,探讨实际操作中管道的创建与访问. 已经了解到,管道本质上是一定数量的估计器连接而成的数据处理流,所以成功创建管道 ...

  8. HashMap是如何进行扩容的?

    HashMap通过resize()方法进行扩容. 源码解析: resize()函数有两种使用情况: 一.当table数组为null时初始化hash表. 二.当table数组不为null时进行扩容. 1 ...

  9. Mybatis注解开发之@CacheNamespace:实现注解二级缓存的使用

    MyBatis二级缓存使用: 官方建议在service使用缓存,但是你也可以直接在mapper层缓存,这里的二级缓存就是直接在Mapper层进行缓存操作 Mybatis的二级缓存实现也十分简单,只要在 ...

  10. Python和JavaScript在使用上有什么区别?

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://www.freecodecamp.org/news/python-vs-javas ...