Weak reference
In computer programming, a weak reference is a reference that does not protect the referenced object from collection by a garbage collector; unlike a strong reference. An object referenced only by weak references – meaning "every chain of references that reaches the object includes at least one weak reference as a link" – is considered weakly reachable, and can be treated as unreachable and so may be collected at any time. Some garbage-collected languages feature or support various levels of weak references, such as Java, C#, Python,[1] Perl, and Lisp.
Garbage collection
Garbage collection is used to clean up unused objects and so reduce the potential for memory leaks and data corruption. There are two main types of garbage collection: tracing and reference counting. Reference counting schemes record the number of references to a given object and collect the object when the reference count becomes zero. Reference-counting cannot collect cyclic (or circular) references because only one object may be collected at a time. Groups of mutually referencing objects which are not directly referenced by other objects and are unreachable can thus become permanently resident; if an application continually generates such unreachable groups of unreachable objects this will have the effect of a memory leak. Weak references (references which are not counted in reference counting) may be used to solve the problem of circular references if the reference cycles are avoided by using weak references for some of the references within the group. For example, Apple's Cocoa framework recommends this approach, by using strong references for parent-to-child references, and weak references for child-to-parent references, thus avoiding cycles.
Weak references are also used to minimize the number of unnecessary objects in memory by allowing the program to indicate which objects are of minor importance by only weakly referencing them.
Variations
Some languages have multiple levels of weak reference strength. For example, Java has, in order of decreasing strength, soft, weak, and phantom references, defined in the package java.lang.ref.[2] Each reference type has an associated notion of reachability. The garbage collector (GC) uses an object's type of reachability to determine when to free the object. It is safe for the GC to free an object that is softly reachable, but the GC may decide not to do so if it believes the JVM can spare the memory (e.g. the JVM has lots of unused heap space). The GC will free a weakly reachable object as soon as the GC notices the object. Unlike the other reference types, a phantom reference cannot be followed. On the other hand, phantom references provide a mechanism to notify the program when an object has been freed (notification is implemented using ReferenceQueues).
Some non-garbage-collected languages, such as C++, provide weak/strong reference functionality as part of supporting garbage collection libraries. In the case of C++, normal pointers are weak and smart pointers are strong; although pointers are not true weak references, as weak references are supposed to know when the object becomes unreachable.
Examples
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.
Java
Java was the first main language to introduce strong reference as the default object reference. Previously (ANSI) C only had weak references. However it was noted by David Hostettler Wain and Scott Alexander Nesmith that event trees were not evaporating properly. Thus strong/weak references of counted and uncounted references was derived (~1998).
If a weak reference is created, and then elsewhere in the code get()
is used to get the actual object, the weak reference isn't 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.[3]
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); // only r.get() becomes null System.out.println("after gc: r=" + r.get() + ", static=" + sr.get()); } }
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
|a s1 s2| 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; __assign NSString *str2; } @property (nonatomic, weak) NSString *str3; @property (nonatomic, assign) NSString *str4; @end
The difference between weak
(__weak
) and assign
(__assign
) 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 assign
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). Older versions of Mac OS X, iOS, and GNUstep support only assign
references as weak ones.
Vala
class Node { public weak Node prev; // a weak reference is used to avoid circular references between nodes of a list public Node next; }
See also
Notes
- ↑ 8.8. weakref — Weak references, The Python Standard Library
- ↑ Nicholas, Ethan (May 4, 2006). "Understanding Weak References". java.net. Retrieved October 1, 2010.
- ↑ weblogs.java.net Java Examples
External links
C++
Java
Nicholas, Ethan (May 4, 2006). "Understanding Weak References". java.net. Retrieved October 1, 2010.
- RCache - Java Library for weak/soft reference based cache
- Java theory and practice: Plugging memory leaks with weak references
Python
- Python Weak References
- Fred L. Drake, Jr., PEP 205: Weak References, Python Enhancement Proposal, January 2001.
|