Weak references can be useful when keeping a list of the current variables being referenced in the application. This list must have weak links to the objects. Otherwise, once objects are added to the list, they will be referenced by it and will persist for the duration of the program.
C++ C++ has a class, a kind of
smart pointer. import std; using std::shared_ptr; using std::weak_ptr; shared_ptr myInts = std::make_shared(5); weak_ptr weakPtr = myInts;
C# C# has the class. using System; using System.Collections.Generic; Dictionary() myDict = new();
Java Java 1.2 in 1998 introduced two kinds of weak references, one known as a "soft reference" (intended to be used for maintaining GC-managed in-memory caches, but which doesn't work very well in practice on some platforms with dynamic heap like Android) and the other simply as a "weak reference". It also added a related experimental mechanism dubbed "phantom references" as an alternative to the dangerous and inefficient finalize() mechanism. If a weak reference is created, and then elsewhere in the code get() is used to get the actual object, the weak reference is not strong enough to prevent garbage collection, so it may be (if there are no strong references to the object) that get() suddenly starts returning null. package org.wikipedia.examples; import java.lang.ref.WeakReference; public class ReferenceTest { public static void main(String[] args) throws InterruptedException { WeakReference r = new WeakReference("I'm here"); String s = "I'm here"; System.out.printf("Before gc: r=%s, static=%s%n", r.get(), s); System.gc(); // assume GC is run Thread.sleep(100); // Only r.get() becomes null. System.out.printf("After gc: r=%s, static=%s%n", r.get(), s); } } Another use of weak references is in writing a
cache. Using, for example, a weak
hash map, one can store in the cache the various referred objects via a weak reference. When the garbage collector runs — when for example the application's memory usage gets sufficiently high — those cached objects which are no longer directly referenced by other objects are removed from the cache.
Smalltalk s1 := 'hello' copy. "that's a strong reference" s2 := 'world' copy. "that's a strong reference" a := WeakArray with:s1 with:s2. a printOn: Transcript. ObjectMemory collectGarbage. a printOn: Transcript. "both elements still there" s1 := nil. "strong reference goes away" ObjectMemory collectGarbage. a printOn: Transcript. "first element gone" s2 := nil. "strong reference goes away" ObjectMemory collectGarbage. a printOn: Transcript. "second element gone"
Lua weak_table = setmetatable({}, {__mode="v"}) weak_table.item = {} print(weak_table.item) collectgarbage() print(weak_table.item)
Objective-C 2.0 In
Objective-C 2.0, not only garbage collection, but also
automatic reference counting will be affected by weak references. All variables and properties in the following example are weak. @interface WeakRef : NSObject { __weak NSString *str1; __unsafe_unretained NSString *str2; } @property (nonatomic, weak) NSString *str3; @property (nonatomic, unsafe_unretained) NSString *str4; @end The difference between weak (__weak) and unsafe_unretained (__unsafe_unretained) is that when the object the variable pointed to is being deallocated, whether the value of the variable is going to be changed or not. weak ones will be updated to
nil and the unsafe_unretained one will be left unchanged, as a
dangling pointer. The weak references is added to Objective-C since
Mac OS X 10.7 "Lion" and
iOS 5, together with
Xcode 4.1 (4.2 for iOS), and only when using ARC. Older versions of Mac OS X, iOS, and GNUstep support only unsafe_unretained references as weak ones.
PHP PHP has the class. $obj = new stdClass(); $weakref = WeakReference::create($obj); var_dump($weakref->get()); unset($obj); var_dump($weakref->get());
Python Python has the module. import gc import weakref from weakref import ReferenceType class Egg: def spam(self) -> None: print("I'm alive!") obj: Egg = Egg() weak_obj: ReferenceType[Egg] = weakref.ref(obj) weak_obj().spam() • prints: I'm alive! obj: str = "Something else" • gc.collect() returns an int print(f"Number of unreachable objects collected: {gc.collect()}") • prints: Number of unreachable objects collected: 35 weak_obj().spam() • Traceback (most recent call last): • File "", line 1, in • AttributeError: 'NoneType' object has no attribute 'spam'
Rust Rust has a object. use std::rc::Rc; use std::rc::Weak; let strong_ptr: Rc = Rc::new(5); let weak_ptr: Weak = Rc::downgrade(&strong_ptr);
Vala Vala has the keyword. class Node { public weak Node prev; // a weak reference is used to avoid circular references between nodes of a doubly-linked list public Node next; } == See also ==