fbpx
维基百科

弱引用

计算机程序设计中,弱引用与强引用相对,是指不能确保其引用的对象不会被垃圾回收器回收的引用。一个对象若只被弱引用所引用,则被认为是不可访问(或弱可访问)的,并因此可能在任何时刻被回收。一些配有垃圾回收机制的语言,如JavaC#PythonPerlLisp等都在不同程度上支持弱引用。

垃圾回收

垃圾回收用来清理不会再使用的对象,从而降低内存泄露和数据损坏的可能性。垃圾回收主要有两种类型:追踪和引用计数。引用计数会记录给定对象的引用个数,并在引用个数为零时收集该对象。由于一次仅能有一个对象被回收,引用计数无法回收循环引用的对象。一组相互引用的对象若没有被其它对象直接引用,并且不可访问,则会永久存活下来。一个应用程序如果持续地产生这种不可访问的对象群组,就会发生内存泄漏。在对象群组内部使用弱引用(即不会在引用计数中被计数的引用)有时能避免出现引用环,因此弱引用可用于解决循环引用的问题。如Apple的Cocoa框架就推荐使用这种方法,具体为,在父对子引用时使用强引用,子对父引用时使用弱引用,从而避免了循环引用。[1] (页面存档备份,存于互联网档案馆

程序对一些对象只进行弱引用,通过此法可以指明哪些对象是不重要的,因此弱引用也用于尽量减少内存中不必要的对象存在的数量。

变种

有些语言包含多种强度的弱引用。例如Java,在java.lang.ref[1][2]包中定义了软引用、弱引用和虚引用,引用强度依次递减。每种引用都有相对应的概念。垃圾回收器(GC)通过判断对象的可访问性类型来确定何时回收该对象。当一个对象是软可访问的,垃圾回收器就可以安全回收这个对象,但如果垃圾回收器认为JVM还能空出可用内存(比如JVM还有大量未使用的堆空间),则有可能不会立刻回收软可访问的对象。但对于弱可访问的对象,一旦被垃圾回收器注意到,就会被回收。和其他引用种类不同,虚引用无法跟踪。但另一方面,虚引用提供了一种机制,当一个对象被回收时程序可以得到通知(实现于ReferenceQueues[3])。 一些未配有垃圾回收机制的语言,比如C++,也提供强/弱引用的功能,以作为对垃圾回收库的支持。在C++中,普通指针可看做弱引用,智能指针可看做强引用,尽管指针不能算"真正"的弱引用,因为弱引用应该能知道何时对象变成不可访问的了。

示例

弱引用可用于在应用程序中维护一个当前被引用的对象的列表。该列表必须弱引用到那些对象,否则一旦对象被添加到列表中,由于它们被列表引用了,在程序运行期间将永远不会被回收。

Java

Java是第一个将强引用作为默认对象引用的主流语言。之前的(ANSI)C语言只支持弱引用。而后David Hostettler Wain和Scott Alexander Nesmith注意到事件树无法正常释放的问题,结果在大约1998年,推出了分别会被计数和不会被计数的强、弱引用。 如果创建了一个弱引用,然后在代码的其它地方用 get()获得真实对象,由于弱引用无法阻止垃圾回收,get()随时有可能开始返回 null(假如对象没有被强引用)。[4]

import java.lang.ref.WeakReference; public class ReferenceTest { public static void main(String[] args) throws InterruptedException { WeakReference r = new WeakReference(new String("I'm here")); WeakReference sr = new WeakReference("I'm here"); System.out.println("before gc: r=" + r.get() + ", static=" + sr.get()); System.gc(); Thread.sleep(100); //只有r.get()变为null System.out.println("after gc: r=" + r.get() + ", static=" + sr.get()); } } 

弱引用还可以用来实现缓存。例如用弱哈希表,即通过弱引用来缓存各种引用对象的哈希表。当垃圾回收器运行时,假如应用程序的内存占用量高到一定程度,那些不再被其它对象所引用的缓存对象就会被自动释放。

Smalltalk

|a s1 s2| s1 := 'hello' copy. "这是个强引用" s2 := 'world' copy. "这是个强引用" a := WeakArray with:s1 with:s2. a printOn: Transcript. ObjectMemory collectGarbage. a printOn: Transcript. "两个元素都还在" s1 := nil. "移除强引用" ObjectMemory collectGarbage. a printOn: Transcript. "第一个元素消失" s2 := nil. "移除强引用" ObjectMemory collectGarbage. a printOn: Transcript. "第二个元素消失" 

Lua

weak_table = setmetatable({}, {__mode="v"}) weak_table.item = {} print(weak_table.item) collectgarbage() print(weak_table.item) 

Objective-C 2.0

在Objective-C 2.0中,除了垃圾回收,自动引用计数也会受弱引用的影响。下面这个例子中的所有变量和属性都是弱引用。

@interface WeakRef : NSObject {  __weak NSString *str1;  __assign NSString *str2; }   @property (nonatomic, weak) NSString *str3; @property (nonatomic, assign) NSString *str4;   @end 

weak(__weak)和assign(__assign)的区别在于,当变量指向的对象被重新分配时,变量的值是否会跟着改变。weak声明的变量会变为nil,而assign声明的变量则会保持不变,成为一个悬摆指针。从Mac OX 10.7 “狮子”系统和iOS 5开始,随着Xcode 4.1版本的推出,weak引用被引入到Objective-C语言中(4.2版本开始支持iOS)。老版本的Mac OS X、iOS和GNUstep仅支持用assign声明弱引用。

Vala

class Node {  public weak Node prev; //弱引用可避免列表中的节点之间出现循环引用  public Node next; } 

Python

>>> import weakref >>> import gc >>> class Egg: ...  def spam(self): ...  print("I'm alive!") ... >>> obj = Egg() >>> weak_obj = weakref.ref(obj) >>> weak_obj().spam() I'm alive! >>> obj = "Something else" >>> gc.collect() 35 >>> weak_obj().spam() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'spam' 

参考文献

  1. ^ . [2013-12-28]. (原始内容存档于2022-06-06). 
  2. ^ Nicholas, Ethan. "Understanding Weak References" 互联网档案馆的,存档日期2010-08-19.. java.net (页面存档备份,存于互联网档案馆). 发布于2006年5月4日. 访问于2010年10月1日
  3. ^ . [2013-12-28]. (原始内容存档于2011-09-30). 
  4. ^ weblogs.java.net Java Examples 互联网档案馆的,存档日期2010-08-19.

弱引用, 在计算机程序设计中, 与强引用相对, 是指不能确保其引用的对象不会被垃圾回收器回收的引用, 一个对象若只被所引用, 则被认为是不可访问, 或弱可访问, 并因此可能在任何时刻被回收, 一些配有垃圾回收机制的语言, 如java, python, perl, lisp等都在不同程度上支持, 目录, 垃圾回收, 变种, 示例, java, smalltalk, objective, vala, python, 参考文献垃圾回收, 编辑主条目, 垃圾回收, 计算机科学, 垃圾回收用来清理不会再使用的对象, 从而降低. 在计算机程序设计中 弱引用与强引用相对 是指不能确保其引用的对象不会被垃圾回收器回收的引用 一个对象若只被弱引用所引用 则被认为是不可访问 或弱可访问 的 并因此可能在任何时刻被回收 一些配有垃圾回收机制的语言 如Java C Python Perl Lisp等都在不同程度上支持弱引用 目录 1 垃圾回收 2 变种 3 示例 3 1 Java 3 2 Smalltalk 3 3 Lua 3 4 Objective C 2 0 3 5 Vala 3 6 Python 4 参考文献垃圾回收 编辑主条目 垃圾回收 计算机科学 垃圾回收用来清理不会再使用的对象 从而降低内存泄露和数据损坏的可能性 垃圾回收主要有两种类型 追踪和引用计数 引用计数会记录给定对象的引用个数 并在引用个数为零时收集该对象 由于一次仅能有一个对象被回收 引用计数无法回收循环引用的对象 一组相互引用的对象若没有被其它对象直接引用 并且不可访问 则会永久存活下来 一个应用程序如果持续地产生这种不可访问的对象群组 就会发生内存泄漏 在对象群组内部使用弱引用 即不会在引用计数中被计数的引用 有时能避免出现引用环 因此弱引用可用于解决循环引用的问题 如Apple的Cocoa框架就推荐使用这种方法 具体为 在父对子引用时使用强引用 子对父引用时使用弱引用 从而避免了循环引用 1 页面存档备份 存于互联网档案馆 程序对一些对象只进行弱引用 通过此法可以指明哪些对象是不重要的 因此弱引用也用于尽量减少内存中不必要的对象存在的数量 变种 编辑有些语言包含多种强度的弱引用 例如Java 在java lang ref 1 2 包中定义了软引用 弱引用和虚引用 引用强度依次递减 每种引用都有相对应的可访问性概念 垃圾回收器 GC 通过判断对象的可访问性类型来确定何时回收该对象 当一个对象是软可访问的 垃圾回收器就可以安全回收这个对象 但如果垃圾回收器认为JVM还能空出可用内存 比如JVM还有大量未使用的堆空间 则有可能不会立刻回收软可访问的对象 但对于弱可访问的对象 一旦被垃圾回收器注意到 就会被回收 和其他引用种类不同 虚引用无法跟踪 但另一方面 虚引用提供了一种机制 当一个对象被回收时程序可以得到通知 实现于ReferenceQueues 3 一些未配有垃圾回收机制的语言 比如C 也提供强 弱引用的功能 以作为对垃圾回收库的支持 在C 中 普通指针可看做弱引用 智能指针可看做强引用 尽管指针不能算 真正 的弱引用 因为弱引用应该能知道何时对象变成不可访问的了 示例 编辑弱引用可用于在应用程序中维护一个当前被引用的对象的列表 该列表必须弱引用到那些对象 否则一旦对象被添加到列表中 由于它们被列表引用了 在程序运行期间将永远不会被回收 Java 编辑 Java是第一个将强引用作为默认对象引用的主流语言 之前的 ANSI C语言只支持弱引用 而后David Hostettler Wain和Scott Alexander Nesmith注意到事件树无法正常释放的问题 结果在大约1998年 推出了分别会被计数和不会被计数的强 弱引用 如果创建了一个弱引用 然后在代码的其它地方用 get 获得真实对象 由于弱引用无法阻止垃圾回收 get 随时有可能开始返回 null 假如对象没有被强引用 4 import java lang ref WeakReference public class ReferenceTest public static void main String args throws InterruptedException WeakReference r new WeakReference new String I m here WeakReference sr new WeakReference I m here System out println before gc r r get static sr get System gc Thread sleep 100 只有r get 变为null System out println after gc r r get static sr get 弱引用还可以用来实现缓存 例如用弱哈希表 即通过弱引用来缓存各种引用对象的哈希表 当垃圾回收器运行时 假如应用程序的内存占用量高到一定程度 那些不再被其它对象所引用的缓存对象就会被自动释放 Smalltalk 编辑 a s1 s2 s1 hello copy 这是个强引用 s2 world copy 这是个强引用 a WeakArray with s1 with s2 a printOn Transcript ObjectMemory collectGarbage a printOn Transcript 两个元素都还在 s1 nil 移除强引用 ObjectMemory collectGarbage a printOn Transcript 第一个元素消失 s2 nil 移除强引用 ObjectMemory collectGarbage a printOn Transcript 第二个元素消失 Lua 编辑 weak table setmetatable mode v weak table item print weak table item collectgarbage print weak table item Objective C 2 0 编辑 在Objective C 2 0中 除了垃圾回收 自动引用计数也会受弱引用的影响 下面这个例子中的所有变量和属性都是弱引用 interface WeakRef NSObject weak NSString str1 assign NSString str2 property nonatomic weak NSString str3 property nonatomic assign NSString str4 end weak weak 和assign assign 的区别在于 当变量指向的对象被重新分配时 变量的值是否会跟着改变 weak声明的变量会变为nil 而assign声明的变量则会保持不变 成为一个悬摆指针 从Mac OX 10 7 狮子 系统和iOS 5开始 随着Xcode 4 1版本的推出 weak引用被引入到Objective C语言中 4 2版本开始支持iOS 老版本的Mac OS X iOS和GNUstep仅支持用assign声明弱引用 Vala 编辑 class Node public weak Node prev 弱引用可避免列表中的节点之间出现循环引用 public Node next Python 编辑 gt gt gt import weakref gt gt gt import gc gt gt gt class Egg def spam self print I m alive gt gt gt obj Egg gt gt gt weak obj weakref ref obj gt gt gt weak obj spam I m alive gt gt gt obj Something else gt gt gt gc collect 35 gt gt gt weak obj spam Traceback most recent call last File lt stdin gt line 1 in lt module gt AttributeError NoneType object has no attribute spam 参考文献 编辑 java lang ref 2013 12 28 原始内容存档于2022 06 06 Nicholas Ethan Understanding Weak References 互联网档案馆的存檔 存档日期2010 08 19 java net 页面存档备份 存于互联网档案馆 发布于2006年5月4日 访问于2010年10月1日 ReferenceQueues 2013 12 28 原始内容存档于2011 09 30 weblogs java net Java Examples 互联网档案馆的存檔 存档日期2010 08 19 取自 https zh wikipedia org w index php title 弱引用 amp oldid 72356363, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。