python 垃圾回收机制

简介: 今天讲python 垃圾回收机制

引用计数器回收


一个对象,会记录着自身被引用的个数

每增加一个引用,这个对象的引用计数会自动+1

每减少一个引用,这个对象的引用计数会自动-1


查看引用计数

import sys sys.getrefcount(对象)

关于getrefcount:


getrefcount(object) -> integer

Return the reference count of object.  The count returned is generally

one higher than you might expect, because it includes the (temporary)

reference as an argument to getrefcount().


注意下加粗的两个地方:

  1. 需要获取一个对象的引用次数,而非一个类
  2. 由于你通过getrefcount引用了这个对象,所以总引用次数要比实际多1


来个例子看看吧

import sys
class Uranus:
    pass
u1 = Uranus()
print(sys.getrefcount(u1)-1) # 1
u3 = u2 = u1
print(sys.getrefcount(u1)-1) # 3
del u3
print(sys.getrefcount(u1)-1) # 2
del u2
print(sys.getrefcount(u1)-1) # 1
del u1
print(sys.getrefcount(u1)-1) # NameError: name 'u1' is not defined


引用+1场景

  1. 对象被创建会 +1
    u1=Uranus()
  2. 对象被引用会 +1
    u2=u1
  3. 对象作为参数传入到一个函数中会 +2


import sys
class Uranus:
    pass
u1 = Uranus()
def func(obj):
    print(sys.getrefcount(obj)-1)
func(u1)


为什么会+2呢?python3的有点难理解,但是Python2的可以直接打印一下

print([(i,getattr(func,i)) for i in dir(func)])

可以看到__globals__he funcglobals__都存在u1


  1. 对象作为一个元素,存储在容器中会 +1
    list1=[u1]


引用-1的场景

  1. 对象被销毁
    del u1
  2. 对象被赋予新的值
    u1=Uranus() u1=1
  3. 一个对象离开他的作用域

如上面对象传入某个函数中,当函数执行完成后,引用会立即销毁

  1. 对象所在的容器被销毁
    list1=[u1] del list1

特殊场景-循环引用问题

何为循环引用?怎么去计算?

此时我们需要使用一个模块objpraph

Count objects tracked by the garbage collector with a given class name.

import objgraph # 需要单独下载
class Person:
    pass
class Animal:
    pass
print(objgraph.count("Person")) # 0
print(objgraph.count("Animal")) # 0
P = Person()
A = Animal()
print(objgraph.count("Person")) # 1
print(objgraph.count("Animal")) # 1
P.pet = A
A.master = P
del P
del A
# 正常情况下,如果删除了P和A,应该为0,但由于循环引用,结果为1
print(objgraph.count("Person")) # 1
print(objgraph.count("Animal")) # 1

那这样不是GG思密达了?那怎么阔能!!!真这样的话Python还有谁用呢?


垃圾回收机制


从经历过引用计数器机制仍未被释放掉的对象中,找到循环引用并删除相关对象


何时启动垃圾回收

不是说你创建了一个变量,就会马上开始垃圾回收的!

需要你代码中,新增对象-消亡对象阈值达到某一个零界点是才会启动垃圾回收

如何查看这个阈值呢?需要引入GC模块

import gc
print(gc.get_threshold())
output:
(700, 10, 10)

代码的结果是一个元组,后面两位之后说,700代表python设置的阈值


怎么找到循环引用

  1. 搜集所有容器对象,通过双向列表进行引用

容器对象:list couple dict ...

非容器对象:a=10 ...

  1. 针对每一个容器对象,通过一个变量gc_refs来记录当前对应的引用计数
  2. 对于每一个容器对象,找到它引用的容器对象,并将这个容器对象的引用计数-1
  3. 如果经历以上三次,如果一个容器对象的引用次数为0,就代表可以被回收了


通过上面的循环引用查找,也许有的人认为比较简单,但是如果一个大的项目,存在着成千上万的容器对象,这么每次去检测岂不是要累死?

python考虑到此处,所以创建了一套回收机制,叫做分代回收


分代回收

何为分代回收,当第一次检测完成后,部分的容器对象没有为0,则将其从0代移动至1代对象中,当检测10次后,在第11次时,会再次扫描0代1代的对象,当101次,即1代对象也被检测了10次,仍存在未被回收的容器对象时,会将器移动至2代中。多像爷爸孙....

至于为什么是10,就是刚才我们查看gc.get_threshold()得到的元组后两个字段。

当然我们也可以进行手动设置:

gc.set_threshold(100,5,5)

但劝你没事儿还是别瞎折腾....


垃圾回收的开启、关闭、状态查询

垃圾回收机制,默认都是开启的,当然我们可以进行调整

gc.disable() gc.enable() gc.isenabled()


如何手动触发垃圾回收

通过gc.collect()手动触发垃圾回收。

此处需要注意一点,即便目前的垃圾回收机制处于关闭状态,一样可以手动触发。


如何避免循环引用



使用弱引用模块

import weakref
A.master = weakref.ref(P) # 此时会生成弱引用


何为弱引用,即在引用的时候,不会是计数器+1

但是weakref.ref只是针对单个引用的,如果是多个呢?

使用:

weakref.WeakKeyDictionary
weakref.WeakValueDictionary
weakref.WeakSet


手动使引用计数-1

A.master = None

通过重新赋值的方法,是不是也可以达到这种方式呢?




相关文章
|
29天前
|
缓存 监控 算法
Python内存管理:掌握对象的生命周期与垃圾回收机制####
本文深入探讨了Python中的内存管理机制,特别是对象的生命周期和垃圾回收过程。通过理解引用计数、标记-清除及分代收集等核心概念,帮助开发者优化程序性能,避免内存泄漏。 ####
41 3
|
4月前
|
缓存 Java Python
python垃圾回收&缓存机制
python垃圾回收&缓存机制
|
4月前
|
存储 算法 Java
关于python3的一些理解(装饰器、垃圾回收、进程线程协程、全局解释器锁等)
该文章深入探讨了Python3中的多个重要概念,包括装饰器的工作原理、垃圾回收机制、进程与线程的区别及全局解释器锁(GIL)的影响等,并提供了详细的解释与示例代码。
41 0
|
5月前
|
机器学习/深度学习 数据采集 数据可视化
使用Python实现深度学习模型:智能垃圾分类与回收系统
【8月更文挑战第20天】 使用Python实现深度学习模型:智能垃圾分类与回收系统
201 1
|
5月前
|
算法 Java 开发者
Python垃圾回收机制
Python垃圾回收机制
|
5月前
|
监控 Java 数据处理
Python内存管理:引用计数与垃圾回收
Python内存管理:引用计数与垃圾回收
52 0
|
7月前
|
Java Python
Python进阶之旅:深入理解变量作用域、垃圾回收、拷贝机制与异常处理
Python进阶之旅:深入理解变量作用域、垃圾回收、拷贝机制与异常处理
|
7月前
|
监控 算法 Java
使用Python的垃圾回收机制来管理内存
使用Python的垃圾回收机制来管理内存
|
8月前
|
存储 Java 程序员
【Python 的内存管理机制专栏】深入解析 Python 的内存管理机制:从变量到垃圾回收
【5月更文挑战第18天】Python内存管理关乎程序性能与稳定性,包括变量存储和垃圾回收。变量存储时,如`x = 10`,`x`指向内存中值的引用。垃圾回收通过引用计数自动回收无引用对象,防止内存泄漏。了解此机制可优化内存使用,避免循环引用等问题,提升程序效率和稳定性。深入学习内存管理对成为优秀Python程序员至关重要。
72 5
【Python 的内存管理机制专栏】深入解析 Python 的内存管理机制:从变量到垃圾回收
|
7月前
|
算法 Java Python
Python教程:深入了解Python垃圾回收机制
在Python中,垃圾回收(Garbage Collection)是一种自动管理内存的机制,它可以自动识别和清理不再使用的对象,释放它们占用的内存空间,以提高内存利用率和程序性能。
104 3