当对象在运行时解除分配时,请确保nil或null值

时间:2018-09-07 08:42:33

标签: memory-management compiler-construction garbage-collection automatic-ref-counting

引用计数和ARC视角
在Swift或Objective-C中,如果引用计数器变为零,则对象将被释放,指向该对象的每个指针值(包括弱变量或属性)都将变为NULL。 他们是怎么做到的?

手动内存管理的观点
在C或C ++中,如果我们释放内存,则只会释放内存。如果我们希望它为NULL,则我们手动分配NULL。只为我们需要的东西付款,我们不会得到额外的收益。

自动GC视角
在Java中,VM监视器对象具有时间间隔的参考用法并收集它们。无需设置空值。但是有一种类型WeakReference确实允许收集器在引用期间在标记阶段忽略某些对象。

我的问题是,从编译器或VM的角度来看,如何确保将nilnull的值分配给先前引用该对象的变量?

1 个答案:

答案 0 :(得分:1)

Holger says in a comment一样,该问题的措词并不正确。您的问题还以基于引用计数的集合为前提,该集合不适用于循环数据结构,例如:

class LinkedList(object):
    def __init__(self, next = None):
        self.next = next
    def set_next(self, next):
        self.next = next
...
e1 = LinkedList()
e2 = LinkedList(e1)
e1.set_next(e2)

(用Python表达)。当e1.next.next也是e1从而e1.next.next.next是e1时,e1的引用计数是多少? (或更简单地说,如果将e1.next设置为e1本身会怎样?)

传统的Lisp垃圾收集始于Mark and Sweep algorithms(注意:我不知道该网站的总体情况是否良好,但是我扫描了链接的文章,看起来还不错)。现代系统通常具有更高级的方案,例如分代收集,“实时”(线程)收集而不是走走停停的收集和实时收集。请参阅the main wikipedia article,尤其是内容较为全面的Tracing Garbage Collection文章。

请注意,强引用和弱引用之间的主要区别在于,在活动性分析中,即强引用 会被计算在内,即确定其他对象是否需要保留某个对象弱引用不会。我所知道的最经典的示例是在 lookup缓存中需要弱引用的地方,那里有一些复杂的数据结构,例如基于磁盘B树的数据库或类似数据库,其中有些对象可能会被带入内存中使用一段时间,我们希望有一种快速的方法来找出它们是否仍然可用:dictionary[key]是对这些对象的快速但弱引用对象,而database.load(key)可能在加载对象后返回对该对象的强引用

许多实现细节都源于诸如语言本身是否以及如何允许您使用和使用指针之类的问题。具有指针操作的语言(例如C ++)使执行编译时分析变得困难,而其他语言(例如Go)使之变得更容易。

来自Mike Ash's blog

Martin R's comment对这些问题和实际实现进行了很好的总结,其中包括Swift中使用的两个。

Go语言使用escape analysis在堆栈上分配一些对象,而在垃圾回收堆中分配其他对象。