zer*_*uno 5 python garbage-collection
当我对以下短语产生疑问时,我正在阅读文档:
由于收集器补充了 Python 中已使用的引用计数,因此如果您确定您的程序不会创建引用循环,则可以禁用收集器。
这是什么意思?如果我禁用垃圾收集器 ( gc.disable()) 并执行以下操作:
a = 'hi'
a = 'hello'
Run Code Online (Sandbox Code Playgroud)
会'hi'留在记忆中吗?我需要自己释放内存吗?
我从这句话中理解的是,gc 是一个额外的工具,专门用于捕获引用循环,如果禁用它,内存仍然会使用对象的引用计数器自动清理,但不会管理引用循环。是对的吗?
在 CPython 中,当对象的引用计数降至 0 时,对象会立即从内存中清除。
当您重新绑定a到时'hello',字符串对象的引用计数'hi'就会减少。如果它达到 0,它将被从内存中删除。
因此,垃圾收集器只需要处理(间接或直接)相互引用的对象,从而防止引用计数降至 0。
字符串不能引用其他对象,因此垃圾收集器不感兴趣。但是任何可以引用其他内容的东西(例如列表或字典等容器类型,或者任何 Python 类或实例)都可以产生循环引用:
a = [] # Ref count is 1
a.append(a) # A circular reference! Ref count is now 2
del a # Ref count is decremented to 1
Run Code Online (Sandbox Code Playgroud)
垃圾收集器检测这些循环引用;没有其他引用a,所以最终 gc 进程打破了循环,让引用计数自然下降到 0。
顺便说一句,Python 编译器将字符串文字(例如'hi'和'hello'作为常量)与生成的字节码捆绑在一起,因此,始终至少有一个对此类对象的引用。此外,源代码中使用的与正则表达式匹配的字符串文字[a-zA-Z0-9_]也会被保留;制成单例以减少内存占用,因此使用相同字符串文字的其他代码块将保存对相同共享字符串的引用。