程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2024-11(2)

Python3循环引用还是会自动垃圾回收的。

发布于2020-03-14 19:25     阅读(1803)     评论(0)     点赞(16)     收藏(5)


以前都听说Python循环引用会导致引用数无法清零,所以不能垃圾回收,会内存泄漏,需要删除引用关系或者用gc.collect()才能进行正常垃圾回收。

但做了下实验,好像还是会自动回收循环引用的变量,在约44对循环引用变量时会首次清理,之后大约每产生200对的垃圾就会清一次,但也没清干净,总是会有残留上几个,而且听说了改__del__会影响垃圾回收,实质上也不会影响。

进程内存监控,可以看出内存大小基本没变,还是符合认知的。

====运行环境====

win10 1903
Python 3.7.5 64bit

=====代码=====

  1. import psutil
  2. class A:
  3. t = 0
  4. def __del__(self):
  5. A.t += 1
  6. class B:
  7. t = 0
  8. def __del__(self):
  9. B.t += 1
  10. if __name__ == '__main__':
  11. pid = os.getpid()
  12. at, bt = 0, 0
  13. for i in range(10000):
  14. a, b = A(), B()
  15. a.b, b.a = b, a
  16. #del a, b
  17. if A.t != at or B.t != bt:
  18. print(f'No_{i}: (d_i: {i - at}, d_a: {A.t - at}, d_b: {B.t - bt})')
  19. print('Used Memory:', psutil.Process(pid).memory_info().rss / 1024 / 1024, 'MB')
  20. at, bt = A.t, B.t

====打印结果====

No_44: (d_i: 44, d_a: 43, d_b: 43)
Used Memory: 13.69921875 MB
No_236: (d_i: 193, d_a: 190, d_b: 190)
Used Memory: 13.8046875 MB
No_431: (d_i: 198, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_626: (d_i: 200, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_822: (d_i: 202, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_1017: (d_i: 203, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_1212: (d_i: 204, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_1407: (d_i: 206, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_1603: (d_i: 208, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_1798: (d_i: 209, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_1993: (d_i: 210, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_2188: (d_i: 212, d_a: 212, d_b: 212)
Used Memory: 13.8046875 MB
No_2384: (d_i: 196, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_2579: (d_i: 197, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_2774: (d_i: 198, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_2969: (d_i: 200, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_3165: (d_i: 202, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_3360: (d_i: 203, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_3555: (d_i: 204, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_3750: (d_i: 206, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_3946: (d_i: 208, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_4141: (d_i: 209, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_4336: (d_i: 210, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_4531: (d_i: 212, d_a: 211, d_b: 211)
Used Memory: 13.8046875 MB
No_4727: (d_i: 197, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_4922: (d_i: 198, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_5117: (d_i: 199, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_5312: (d_i: 201, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_5508: (d_i: 203, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_5703: (d_i: 204, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_5898: (d_i: 205, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_6093: (d_i: 207, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_6289: (d_i: 209, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_6484: (d_i: 210, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_6679: (d_i: 211, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_6874: (d_i: 213, d_a: 211, d_b: 211)
Used Memory: 13.8046875 MB
No_7070: (d_i: 198, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_7265: (d_i: 199, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_7460: (d_i: 200, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_7655: (d_i: 202, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_7851: (d_i: 204, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_8046: (d_i: 205, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_8241: (d_i: 206, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_8436: (d_i: 208, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_8632: (d_i: 210, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_8827: (d_i: 211, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_9022: (d_i: 212, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_9217: (d_i: 214, d_a: 211, d_b: 211)
Used Memory: 13.8046875 MB
No_9413: (d_i: 199, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_9608: (d_i: 200, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB
No_9803: (d_i: 201, d_a: 193, d_b: 193)
Used Memory: 13.8046875 MB
No_9998: (d_i: 203, d_a: 194, d_b: 194)
Used Memory: 13.8046875 MB

====实验结束====

之前了解Python3的print是线程安全的,但在这个垃圾回收的实验里,如果在__del__函数里添加print,在自动回收垃圾时有一定概率(概率小于20%)报出非阻塞的错误。
不过似乎只在Power shell会报错,在cmd里似乎不会报错,但考虑到cmd的输出远快于Power shell,可能是达不到并发标准所以在cmd才不报错。
而且是在此期间所有同时被回收的对象都会同时报错,还不太了解什么原因,不知道是不是并发回收对象的问题。

报错信息如下,一般一出就是4百条同时来:

RuntimeError: reentrant call inside <_io.BufferedWriter name='<stdout>'>



所属网站分类: 技术文章 > 博客

作者:恋爱后女盆友的变化

链接:https://www.pythonheidong.com/blog/article/259565/6847169d7f3fa0972ff9/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

16 0
收藏该文
已收藏

评论内容:(最多支持255个字符)