一点疑问

2020-04-16 15:19:37 +08:00
 iamdaguduizhang
a = 'aaaa'
print(id(a))
del a
b = 'aaaa'
print(id(b))

# 为什么两次打印出的内存地址是一样的,看起来 del a 之后'aaaa'并没有被垃圾回收,引用计数不是具有实时性吗?
# 如果是在交互式 ipython 下,两次打印倒是不一样的。emm 看了 py 文件的运行机制也没有搞清楚这个问题,可能是这个运行机制看的不是很透彻,求大佬指点。
1852 次点击
所在节点    Python
13 条回复
xcstream
2020-04-16 16:07:34 +08:00
‘aaaa’是常量了 固定住内存地址
xcstream
2020-04-16 16:08:47 +08:00
ipython 在启动后没有'aaaa' 需要生成一个新的
TanLeDeDaNong
2020-04-16 16:18:10 +08:00
具体可以查下 python 的垃圾回收机制,有个问题思考一下:1. python 是不是 del 之后马上垃圾回收, 我理解的并不是 ,是有延时的。2. 为什么命令行会回收,你可以尝试 sleep 一下。
xiri
2020-04-16 16:18:23 +08:00
发生字符串驻留了,Cpython 在编译优化时会尝试重复使用已经存在的不可变对象而不是每次都创建一个新对象(当然,要满足一定的条件)
iamdaguduizhang
2020-04-16 16:38:02 +08:00
@TanLeDeDaNong emm 1.垃圾回收不是一个 del 那么简单诶。2.和 sleep 没有关系的。依然感谢
iamdaguduizhang
2020-04-16 16:39:09 +08:00
@xiri 你是说类似于小整数对象池的那个嘛?
iamdaguduizhang
2020-04-16 16:40:16 +08:00
@xcstream 固定住内存地址? 我在 del 前打印了引用计数发现是 4 诶,
chenstack
2020-04-16 16:48:28 +08:00
的确是有字符串驻留了,但即使没有驻留,这种情况下 id 也是一样的
a = object()
print(id(a))
del a
b = object()
print(id(b))
xiri
2020-04-16 16:55:35 +08:00
@iamdaguduizhang 你可以打印一下"aaaa"的引用计数,a 变量被删掉了,但是"aaaa"这个常量没有哦
import sys
a = "aaaa"
print(sys.getrefcount("aaaa"))
del a
print(sys.getrefcount("aaaa"))
b = "aaaa"
c = "aaaa"
print(sys.getrefcount("aaaa"))

你可以试一下上面的代码,输出是 4 、3 、5,del a 之后"aaaa"的引用减了 1,但是并没有被删掉,如果打印一下 a,b,c 的 id 会发现都是一样的,他们都指向内存中同一个字符串对象。可以看一下下面这个说明,这是 Cpython 的一种编译优化
https://github.com/leisurelicht/wtfpython-cn#-strings-can-be-tricky-sometimes%E5%BE%AE%E5%A6%99%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2-
pompeii
2020-04-16 16:58:29 +08:00
>>> import gc
>>> a = 'aaa'
>>> id(a)
77627920L
>>> del a
>>> gc.collect()
0
>>> b = 'aaa'
>>> id(b)
77629040L

所以垃圾回收应该不是实时的
iamdaguduizhang
2020-04-16 17:11:35 +08:00
@xiri 恩恩,感谢。我明白你说的字符串驻留了。 看起来现在我的疑问变成了第一次打印引用计数的值不是 ipython 里的 1 ? 所以 del 之后还是字符串没有被回收,然后就出现了字符串驻留诶
iamdaguduizhang
2020-04-16 17:15:15 +08:00
@pompeii emm,感觉不能通过 交互式有时间间隔来证明垃圾回收不是实时的诶。
iamdaguduizhang
2020-04-16 17:19:13 +08:00
@chenstack 感谢~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/663094

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX