当对象在运行时释放时,确保nil或null值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当对象在运行时释放时,确保nil或null值相关的知识,希望对你有一定的参考价值。

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

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

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

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

答案

作为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文章。

请注意,强引用和弱引用之间的关键区别在于,在活跃度分析中计算强引用 - 即,在确定是否保留某些对象时,因为某些其他对象需要它 - 而弱引用则不然。我知道哪个人想要弱引用的最经典的例子是在查找缓存中,其中存在一些复杂的数据结构,例如基于磁盘B树的数据库或类似的,其中一些对象可能被带入内存以使用了一段时间,我们希望有一个快速的方法来确定它们是否仍然可用:dictionary[key]将是对象的快速但弱的引用,而database.load(key)返回对该对象的强引用,可能在加载它之后。

许多实现细节源于语言本身是否以及如何允许您使用指针等问题。使用指针操作的语言(例如C ++)使得编译时分析难以进行其他语言(例如Go)变得更容易。

来自Mike Ash's blogMartin R's comment对其中几个问题和实际实现进行了很好的总结,其中包括两个在Swift中使用的问题。

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

以上是关于当对象在运行时释放时,确保nil或null值的主要内容,如果未能解决你的问题,请参考以下文章

自动释放并分配给 nil

当动态创建的对象有父对象时,QML 不会释放大量内存

Linux下内存泄漏工具

在 Swift 中,我如何避免选项和 nil 对象引用?

释放 NSArray 时将对象设置为 nil

iOS 中的 nilNilNULLNSNull 僵尸对象和野指针