« 上一篇下一篇 »

运行时刻之弱引用

时候,虽然程序使用带有垃圾回收机制的语言,但是仍然希望自己管理内存,或者管理部分内存。也就是说,尽管仍然存在一些引用指向某些对象,但程序员知道这些对象不会再被访问。一个来自编译的例子可以说明这一问题。

我们已经看到,词法分析器通常会管理一个符号表,为它碰到的每个标识符创建一个对象。比如,这些对象可能作为词法值被附加于语法分析树中代表这些标识符的叶子结点上。然而,以这些标识符的字符串作为键值构造一个散列表有助于对这些对象进行定位。这个散列表可以在词法分析器碰到一个标识符词法单元时更容易找到对应的对象。

当编译器扫描完标识符I的作用域时,I的符号表对象不再有任何来自语法分析树的引用,也没有来自可能被编译器使用的其他中间结构的引用。然而,在散列表中仍然存在一个指向这个对象的引用。因为散列表是编译器的根集的一部分,所以这个对象不能作为垃圾被回收。如果碰到了另一个词素和不相同的标识符,编译器就会发现I已经过时了,指向I的对象的引用将被删除。然而,如果没有遇到词素相同的其他标识符,那么I的对象仍然是不可回收的,尽管在之后的整个编译过程中它都是无用的。

提出的问题很重要,那么编译器的作者可以设法在标识符的作用域一结束时就在散列表中删除对相应对象的所有引用。然而,一种被称为弱引用(weak reference)的技术支持程序员依靠自动垃圾回收来解决问题,并且不会因为那些实际不再使用的可达对象而给堆区存储带来负担。在这样的系统中,允许将某些引用声明为“弱”引用。弱引用的一个例子是我们刚刚讨论的散列表中的所有引用。当垃圾回收器扫描一个对象时,它不会沿着该对象内的弱引用前进,也不会将它们指向的对象设置为可达的。当然,如果另有一个不弱的引用指向这一个对象,这个对象可能仍然是可达的。

« 上一篇下一篇 »