python基础篇学习(六)之循环引用之内存泄露问题

首先,看下面这个案例

l1 = ['a', 'b']
l2 = ['x', 'y']
l1.append(l2)
print(l1)
print(id(l2), id(l1[2]))
l2.append(l1)
print(l2)
print(id(l1), id(l2[2]))
# 这两个列表存在一种相互引用的关系,就叫做循环引用
----------------------------------------------------------------
# 运行结果:
['a', 'b', ['x', 'y']]
2230756681088 2230756681088
['x', 'y', ['a', 'b', [...]]]
2230756998272 2230756998272

del l1
del l2

现在已经把这两个列表的直接引用全部解除了,但是它们身上的引用计数并没有变成0,它们身上只有它们相互的间接引用,再也没办法取到这两个列表了,所以这两个列表这时候就变成了一个永远回收不了的垃圾,永远占着这两块内存空间,这就叫内存泄漏

其次,了解栈区和堆区

name = '小圆子'
# 见下图,栈区专门用来存放变量名,堆区专门用来存放变量值

在这里插入图片描述

最后,分析最上面的案例

紧接最上面的案例,见下面两张图,下方堆区的两块内存就泄露了,这时候python就提供了一个叫标记清除的解决方案:

标记清除会在你python程序内存空间不够用的时候,将整个程序暂停下来,扫描栈区,把通过栈区所有能引用到的值(不管是通过栈区直接引用还是间接引用到的),都标记为存活状态,一旦发现有通过栈区引用不到的值,都标记为死亡状态,死亡状态的值会直接被清理掉,就算它身上的引用计数不为0,只要访问不到它了,标记清除就会把它标记成垃圾,然后回收掉

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值