垃圾回收,引用计数

引用计数,这是 Python 的垃圾回收策略。
补充一下。解释器(也就是你说的 Shell)负责跟踪对象的引用计数,垃圾收集器负责释放内存。
如何释放?可以通过销毁对象的引用,使引用计数减少至 0。假设 x = 3,以下情况会使 3 这个整型对象的引用计数减少;
函数运行结束,所有局部变量都被销毁,对象的引用计数也就随之减少。
例如 foo(x) 运行结束,x 被销毁;

 

当变量被赋值给另一个对象时,原对象的引用计数也会减少。

例如 x = 4,这时候 3 这个对象的引用计数就减 1 了;使用 del 删除一个变量也会导致对象引用减少。
例如 del x;对象从集合对象中移除。
例如 lst.remove(x);包含对象的集合对象被销毁。
例如 del lst;这些操作都可能使对象变成垃圾回收对象,由垃圾收集器负责收集,当然垃圾收集器也负责处理循环引用对象。

 

import sys


def counter(start=0):
    def addone():
        nonlocal start
        start += 1
        return start

    return addone


c1 = counter(0)
c2 = c1
print(c1())
print(c1())
print(c1())
print(c1())
# 查看引用的地址
print(id(c1))
print(id(c2))
# 查看c2地址的引用计数
print("c2地址的引用计数是:%s" % sys.getrefcount(c2))
# 删除一个引用 del c1 # 查看c2地址的引用计数 print("c2地址的引用计数是:%s" % sys.getrefcount(c2))

  

输出结果:

1
2
3
4
43561712
43561712
c2的引用计数是:3
c2的引用计数是:2

关闭内存回收:

import gc

class ClassA():
    def __init__(self):
        print('object born,id:%s'%str(id(self)))

def f2():
    while True:
        c1 = ClassA()
        c2 = ClassA()
        c1.t = c2
        c2.t = c1
        del c1
        del c2

#python默认是开启垃圾回收的,可以通过下面代码来将其关闭
gc.disable()


f2()

  

手动回收:

import gc

class ClassA():
    def __init__(self):
        print('object born,id:%s'%str(id(self)))

def f2():
    while True:
        c1 = ClassA()
        c2 = ClassA()
        c1.t = c2
        c2.t = c1
        del c1
        del c2
        gc.collect()#手动调用垃圾回收功能,这样在自动垃圾回收被关闭的情况下,也会进行回收

#python默认是开启垃圾回收的,可以通过下面代码来将其关闭
gc.disable()


f2()

  或者不关闭,python默认是会回收垃圾的

import gc


class ClassA():
    def __init__(self):
        print('object born,id:%s' % str(id(self)))


def f2():
    while True:
        c1 = ClassA()
        c2 = ClassA()
        c1.t = c2
        c2.t = c1
        del c1
        del c2


f2()

  

 

posted @ 2018-01-26 15:19  安迪9468  阅读(160)  评论(0编辑  收藏  举报