鱼C论坛

 找回密码
 立即注册
查看: 3298|回复: 4

[技术交流] 【木有百科】垃圾回收机制,你肿么了?(上)

[复制链接]
发表于 2014-9-16 12:13:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 mumudontcry 于 2014-9-17 08:43 编辑

上一讲,木木说了一个跟缓存复用有关的话题,其中这里有几个小错误(当时也不太清楚,也不能说错了)说下:
1、有鱼油提出的代码运行结果跟木木的不一样,当时木木也没有注意到,其实:
在shell(就是idle)下,python能够缓存和复用的数字大小最大是256(为了证明这点,木木的好机油居然一个一个试了出来),也就是说
在idle下
a=256
b=256
a is b的结果一定是True
当a=257之后,以及a等于256以内的小数(不包括246.0这类小数,而是246.1这类)的时候,结果也是False
但是,在把程序写成py文件的时候,不管有多大,都会得到True。于是才有鱼油的关于木木错误的那张截图
2、上一讲的重点其实就是想说明,如果你想使用一个列表的拷贝,那么最好使用分片的方式
当然由于你在a=1 b=1之后再b=2,意思是指针(你可以这么理解)b指向了2这个对象,所以即便a和b缓存复用了同一个对象1,也不会因为改变了b的值而改变a,不知道各位听懂了没

好,这一讲说一些关于python垃圾回收机制的一些奇怪的东西:

对于python的垃圾回收机制,我只能说,太好了,但是……
先说为什么好
在C语言时代(c,c++),程序使用的是自己管理内存的方式,说得清楚一点就是自己可以创建和删除一个空间(new和del),这样的方式很自由,但也同时为内存泄漏和大量悬空指针留下隐患,说简单就是内存里有很多垃圾
后来的java,c#都采用了垃圾回收机制,python也是如此,所谓垃圾回收,就是对每个对象加一个计数器,创建一个对象,该对象就会添加一个计数器,删除这个对象,计数器的值就会减少1,当计数器的值为0的时候,就会自动释放这段内存
在python里,举个例子,创建一个对象就是a=1,此时,1这个对象的计数器会加1,删除这个对象就是a=2,此时1这个对象计数器减一,2这个对象计数器加1,此时1的计数器的值为0,所以,1这个对象被垃圾回收掉了
这样的机制的有点就是:
简单
实用:不需要自己去管理,程序会自动将内存释放
当然也有很明显的缺点
1、由于加入了一个计数器,为了维护这个计数器,需要消耗额外的资源
2、有可能因为循环引用,使得有一些对象永远无法被回收掉
第一个比较容易理解,至于第二个……
看看这个例子:
(这是一个循环引用的例子)
L=[1]
L.append(L)
print(L)
输出结果我不说,你们自己试一试
有没有感到好奇怪?[...]是什么?这在python1.5之前是没有这个的,而且你如果输入了上面的语句,python会无限输出这个列表,直到你电脑崩溃或者强制关闭
[...]代表,这个列表是个循环,它引用了自己
如果你使用上一讲说的getrefcount函数,你会发现函数值是3!(既然是无限列表,为什么只是3?)
我解释一下,为什么这个循环里,只引用了L三次
首先要清楚一个概念(我再强调一遍),python里不存在变量,只有对象!
所以,L=[1]表示,L这个名字(看成指针)指向了[1]这段内存单元,于是,L的函数值加1(创建就会加1)
这里还需要强调一点,列表是一种无类型(或者所有类型)的数组,所以[1]的append一定是一段连续的内存单元
也就是说,L.append(L)表示,L[0]的下一个单元,也就是L[1],跟着一个L,这个时候,相当于(原来的L)L[1]指向了L,于是L的函数值再加1
而在append里有个L,说明引用了L,于是函数值再加1
(就是说append引用了一次L,括号里因为是L,于是L再被引用一次)
所以getrefcount的函数值是3
从图上可以看出,这个列表从此形成一个循环
如果说,此时L=1,按照垃圾回收机制的计数器做法,此时L指向了一个新的对象,那么原来的那个循环的列表的计数器会减少1,可问题是,那段内存单元本身的计数器的值就是3,也就是说,当形成一个循环的时候,循环对象是无法被垃圾回收机制删除的!!
可是我们明明知道,这个循环对象就是垃圾(我们让L引用了新的对象,原来的对象不再需要了),垃圾回收机制就是无法回收!!

同样的,如果让a列表append一个b列表,然后b也append这个a列表,也会形成一个循环,也会让回收机制无法回收那段垃圾!
说好的回收呢?垃圾回收机制,你肿么了?
……………………………………………………………………………………华丽的分割线………………………………………………
提问时间:
请写出循环列表L的所有元素!(我知道是无限个,你们就写前面几个直到可以看出规律就可以了)

************************************************************
关注
木有百科
关注不一样的编程世界
QQ截图20140916115812.png

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
bevin + 3 + 3 + 3 支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-16 13:33:00 | 显示全部楼层
上次弄了个循环,他给我生成了个26+G的文件- -。。还是C盘!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-9-16 15:58:31 | 显示全部楼层
额  我也不清楚???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-16 22:02:48 From FishC Mobile | 显示全部楼层
wei_Y 发表于 2014-9-16 13:33
上次弄了个循环,他给我生成了个26+G的文件- -。。还是C盘!

什么东东
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-9-23 01:09:40 | 显示全部楼层
需要消耗额外的资源
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-13 06:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表