python垃圾回收机制(十分重要)
python垃圾回收机制
总概
python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略,在 Python 内部记录着所有使用中的对象各有多少引用。
在C/C++中采用用户自己管理维护内存的方式。自己管理内存极其自由,可以任意申请内存,但也为大量内存泄露、悬空指针等bug埋下隐患。
如何知道一个对象永远都不能再使用了呢?很简单,就是当这个对象的引用计数值为 0 时,说明这个对象永不再用,自然它就变成了垃圾,需要被回收。
计数表
a = 40 # 创建对象 <40>
b = a # 增加引用, <40> 的计数
c = [b] # 增加引用. <40> 的计数
del a # 减少引用 <40> 的计数
b = 100 # 减少引用 <40> 的计数
c[0] = -1 # 减少引用 <40> 的计数
示例
class Point:
def __init__( self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print class_name, "销毁"
pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # 打印对象的id
del pt1
del pt2
del pt3
结果
3083401324 3083401324 3083401324
Point 销毁
示例执行过程
执行过程:
1.创建Point对象:
pt1 = Point():创建了一个Point对象,其x和y属性默认都是0。pt1是这个对象的第一个引用。
2.复制引用:
pt2 = pt1:pt2现在指向pt1所指向的同一个对象。
pt3 = pt1:同样,pt3也指向pt1所指向的同一个对象。
3.打印对象的id:
print id(pt1), id(pt2), id(pt3):由于pt1、pt2和pt3都指向同一个对象,所以它们打印出的id是相同的。
4.删除引用:
del pt1:删除了pt1这个引用,但对象本身仍然存在,因为还有pt2和pt3指向它。
del pt2:同样,删除了pt2这个引用,但对象仍然因为pt3的引用而存在。
del pt3:最后,删除了pt3这个引用。此时,没有任何引用指向这个Point对象,Python的垃圾回收机制会识别到这个对象不再被使用,并销毁它。
5.析构方法:
当Point对象被销毁时,它的析构方法__del__会被调用。因此,在del pt3之后,会打印出"Point 销毁"。
pt1 = Point():创建了一个Point对象,其x和y属性默认都是0。pt1是这个对象的第一个引用。
2.复制引用:
pt2 = pt1:pt2现在指向pt1所指向的同一个对象。
pt3 = pt1:同样,pt3也指向pt1所指向的同一个对象。
3.打印对象的id:
print id(pt1), id(pt2), id(pt3):由于pt1、pt2和pt3都指向同一个对象,所以它们打印出的id是相同的。
4.删除引用:
del pt1:删除了pt1这个引用,但对象本身仍然存在,因为还有pt2和pt3指向它。
del pt2:同样,删除了pt2这个引用,但对象仍然因为pt3的引用而存在。
del pt3:最后,删除了pt3这个引用。此时,没有任何引用指向这个Point对象,Python的垃圾回收机制会识别到这个对象不再被使用,并销毁它。
5.析构方法:
当Point对象被销毁时,它的析构方法__del__会被调用。因此,在del pt3之后,会打印出"Point 销毁"。
此外
析构方法的调用时机是由Python的垃圾回收机制决定的,它可能在对象不再被引用后的某个不确定的时间点被调用。此外,对于简单的对象,析构方法通常不是必需的,因为Python的内存管理已经足够高效。析构方法主要用于释放非内存资源,如文件句柄、网络连接等。