GC 算法

引用计数

什么是引用计数?

Python GC策略中使用了引用计数,在Python中一切都是对象,而每个对象都有一个obj_refcnt字段,当被其他对象引用时,则该对象obj_refcnt加1,当引用该对象的对象删除后,则obj_refcnt减1,当该对象的引用计数为0时,则该对象就会被Python当作垃圾回收掉

引用计数的优缺点有哪些?

引用技术的优点主要有几个优点

  1. 简单,+1,-1
  2. 实时性较高,不像(例如)其他GC策略,需要等到特定的时间
  3. 避免了集中回收,例如一次GC回收可能很长,因为需要删除的对象过多

引用技术存在的一些问题:

  1. 循环引用

实例证明引用计数的问题?

imprt gc
class Person():
    def __init__(self):
        obj_id = id(self)
        print "Current ID: {id}".format(id=obj_id)

def loop():
    while True:
        p1 = Person()
        p2 = Person()
        p1.id = p2
        p2.id = p1
        del p1
        del p2
gc.disable()
loop()
gc.disable()

标记清除

什么是标记清除?

标记清除的优缺点有哪些?

分代算法

分代算法是什么?

分代算法简单来说就是创建了多个代以存放不同生命周期的对象

分代算法是如何解决问题的?

  • Generation Zero:当触发GC时,Python解释器会对Generation Zero链表上的存在循环引用的对象引用计数减一,如果引用计数为0,则删除该对象,如果引用计数大于0,并且没有循环引用

  • Generation One:创建1代链表并将0代链表上还有引用的对象移动过来,当1代链表也触发GC时,同样如果引用计数为0,则删除该对象,如果引用计数大于0,并且没有循环引用

  • Generation Two:创建2代链表并将1代链表上还有引用的对象移动过俩,当2代链表也触发GC时,同样如果引用计数为0,则删除该对象,如果引用计数不为0,则忽略该对象,继续检测其他对象

除了循环引用的问题,分代算法的其他好处是什么?

有几点好处

  1. 通过分代处理可以灵活控制不通代的GC频率,例如0代频率较高点,是为了避免循环引用导致的内存被大量占用的问题,1代和2代频率较低,这是因为能够被进入到1、2代,尤其是2代,都是经过好几次GC的,说明被引用的多,所以对于这种常驻内存的对象,没必要检测那么频繁

results matching ""

    No results matching ""