Content deleted Content added
→Garbage collection: Underscores in shared_ptr and weak_ptr |
m →Java: HTTP to HTTPS for SourceForge |
||
(39 intermediate revisions by 31 users not shown) | |||
Line 1:
{{Short description|In programming, a reference which does not protect its object from garbage collection}}
In [[computer programming]], a '''weak reference''' is a [[reference (computer science)|reference]] that does not protect the referenced [[object (computer science)|object]] from collection by a [[garbage collection (computer science)|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 memory|unreachable]] and so may be collected at any time. Some garbage-collected languages feature or support various levels of weak references, such as [[C Sharp (programming language)|C#]], [[Lua (programming language)|Lua]], [[Java (programming language)|Java]], [[Lisp (programming language)|Lisp]], [[OCaml]], [[MATLAB]],<ref>[https://uk.mathworks.com/help/matlab/matlab_oop/weak-reference-handles.html]</ref> [[Perl]],
==Uses==
Weak references have a number of common
==Garbage collection==
Line 8 ⟶ 9:
Garbage collection is used to clean up unused objects and so reduce the potential for [[memory leak]]s 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.
A very common case of such strong vs. weak reference distinctions is in tree structures, such as the [[Document Object Model]] (DOM), where parent-to-child references are strong, but child-to-parent references are weak. For example, Apple's [[Cocoa (API)|Cocoa]] framework recommends this approach.<ref>{{cite web|url=https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html|title=Practical Memory Management|website=developer.apple.com}}</ref> Indeed, even when the object graph is not a tree, a tree structure can often be imposed by the notion of object ownership, where ownership relationships are strong and form a tree, and non-ownership relationships are weak and not needed to form the tree – this approach is common in [[C++]] (pre-C++11), using raw pointers as weak references. This approach, however, has the downside of not allowing the ability to detect when a parent branch has been removed and deleted. Since the [[C++11]] standard, a solution was added by using [[Smart_pointer#shared_ptr_and_weak_ptr|shared_ptr
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.{{citation needed|date=February 2023}}
== Variations ==
Some languages have multiple levels of weak reference strength. For example, [[Java (programming language)|Java]] has, in order of decreasing strength, [[soft reference|soft]], weak, and [[phantom reference|phantom]] references, defined in the [[Java package|package]] [[Java Platform, Standard Edition#java.lang.ref|java.lang.ref]].<ref>{{cite web |last=Nicholas |first=Ethan |url=http://weblogs.java.net/blog/2006/05/04/understanding-weak-references |title=Understanding Weak References |work=java.net |date=May 4, 2006 |
In C#, weak references are distinguished by whether they track [[object resurrection]] or not. This distinction does not occur for strong references, as objects are not [[finalization|finalized]] if they have any strong references to them. By default, in C# weak reference do not track resurrection, meaning a weak reference is not updated if an object is resurrected; these are called '''short weak references''', and weak references that track resurrection are called '''long weak references'''.{{sfn|Goldshtein|Zurbalev|Flatow|2012|p=[https://books.google.com/books?id=D3J58cs-i44C
Some non-garbage-collected languages, such as [[C++]], provide weak/strong reference functionality as part of supporting garbage collection libraries. The Boost C++ library provides strong and weak references. It is a mistake to use regular C++ pointers as the ''weak'' counterparts of [[smart pointer]]s because such usage removes the ability to detect when the ''strong'' reference count has gone to 0 and the object has been deleted. Worse yet, it
==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.
===C#===
[[C Sharp (programming language)|C#]] have the {{Mono|WeakReference}} class.<ref>{{cite web |title=Weak References - .NET |url=https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/weak-references |website=learn.microsoft.com |access-date=9 July 2025 |language=en-us}}</ref><ref>{{cite web |title=WeakReference Class (System) |url=https://learn.microsoft.com/en-us/dotnet/api/system.weakreference?view=net-9.0 |website=learn.microsoft.com |access-date=9 July 2025 |language=en-us}}</ref>
<syntaxhighlight lang="csharp">
new Dictionary<int, WeakReference>();
</syntaxhighlight>
===Java===
Java 1.2 in 1998 introduced<ref>{{cite web|url=http://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html|title=WeakReference (Java Platform SE 7 )|website=docs.oracle.com}}</ref> two kinds of weak references, one known as a
If a weak reference is created, and then elsewhere in the code <code>get()</code> is used to get the actual object, the weak reference
▲Java 1.2 in 1998 introduced<ref>{{cite web|url=http://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html|title=WeakReference (Java Platform SE 7 )|website=docs.oracle.com}}</ref> 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<ref>{{cite web|url=https://developer.android.com/reference/java/lang/ref/SoftReference.html|title=SoftReference - Android Developers|website=developer.android.com}}</ref>) 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.<ref>{{cite web|url=http://docs.oracle.com/javase/7/docs/api/java/lang/ref/PhantomReference.html|title=PhantomReference (Java Platform SE 7 )|website=docs.oracle.com}}</ref>
▲If a weak reference is created, and then elsewhere in the code <code>get()</code> 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 <code>get()</code> suddenly starts returning null.<ref>http://weblogs.java.net/blog/2006/05/04/understanding-weak-references Java Examples</ref>
▲<source lang=java>
import java.lang.ref.WeakReference;
public class ReferenceTest {
▲ WeakReference r = new WeakReference("I'm here");
▲ StrongReference sr = new StrongReference("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());
}▼
}
</syntaxhighlight>
Another use of weak references is in writing a [[cache (computing)|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===
<syntaxhighlight lang="smalltalk">
|a s1 s2|
Line 69 ⟶ 71:
ObjectMemory collectGarbage.
a printOn: Transcript. "second element gone"
</syntaxhighlight>
===Lua===
<syntaxhighlight lang="lua">
weak_table = setmetatable({}, {__mode="v"})
weak_table.item = {}
Line 79 ⟶ 80:
collectgarbage()
print(weak_table.item)
</syntaxhighlight>
===Objective-C 2.0===
In [[Objective-C]] 2.0, not only garbage collection, but also [[Reference counting|automatic reference counting]] will be affected by weak references. All variables and properties in the following example are weak.
<
@interface WeakRef : NSObject
{
Line 94 ⟶ 95:
@end
</syntaxhighlight>
The difference between <code>weak</code> (<code>__weak</code>) and <code>unsafe_unretained</code> (<code>__unsafe_unretained</code>) 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. <code>weak</code> ones will be updated to [[Null pointer|<code>nil</code>]] and the <code>unsafe_unretained</code> one will be left unchanged, as a [[dangling pointer]]. The <code>weak</code> references is added to Objective-C since [[Mac OS X Lion|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 <code>unsafe_unretained</code> references as weak ones.
===
[[PHP]] have the {{Mono|WeakReference}} class.<ref>{{cite web |title=PHP: WeakReference - Manual |url=https://www.php.net/manual/en/class.weakreference.php |website=www.php.net |access-date=9 July 2025 |language=en}}</ref>
<source lang=vala>▼
<syntaxhighlight lang="php">
class Node {▼
$obj = new stdClass();
public weak Node prev; // a weak reference is used to avoid circular references between nodes of a list▼
$weakref = WeakReference::create($obj);
public Node next;▼
var_dump($weakref->get());
unset($obj);
var_dump($weakref->get());
</syntaxhighlight>
===
[[Python (programming language)|Python]] have the {{Mono|weakref}} module.<ref>{{cite web |title=weakref — Weak references |url=https://docs.python.org/3/library/weakref.html |website=Python documentation |access-date=9 July 2025 |language=en}}</ref>
<syntaxhighlight lang="pycon">
>>> import weakref
>>> import gc
Line 124 ⟶ 129:
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'spam'
</syntaxhighlight>
===Vala===
[[Vala (programming language)|Vala]] use the {{Mono|weak}} keyword.<ref>{{cite web |title=4.9. Weak References - Vala Documentation |url=https://docs.vala.dev/tutorials/programming-language/main/04-00-advanced-features/04-09-weak-references.html |website=docs.vala.dev |access-date=9 July 2025}}</ref>
▲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;
</syntaxhighlight>
== See also ==
Line 135 ⟶ 149:
{{reflist|30em}}
{{refbegin}}
* {{Cite book | isbn = 978-1-4302-4458-5 | title = Pro .NET Performance: Optimize Your C# Applications | last1 = Goldshtein | first1 = Sasha | last2 = Zurbalev | first2 = Dima | last3 = Flatow | first3 = Ido | year = 2012 | publisher = Apress | url =
{{refend}}
Line 146 ⟶ 160:
=== Java ===
* [http://www.pawlan.com/monica/articles/refobjs/ Java developer article: 'Reference Objects and Garbage Collection']
* {{cite web |last=Nicholas |first=Ethan |url=http://weblogs.java.net/blog/2006/05/04/understanding-weak-references |title=Understanding Weak References |work=java.net |date=May 4, 2006 |
* [
* [http://www.ibm.com/developerworks/java/library/j-jtp11225/ Java theory and practice: Plugging memory leaks with weak references]
=== PHP ===
* [https://www.php.net/manual/en/class.weakreference.php Weak References]
=== Python ===
* [https://docs.python.org/3/library/weakref.html weakref — Weak references — Python 3 documentation]
* Fred L. Drake, Jr., ''[https://www.python.org/dev/peps/pep-0205/ PEP 205: Weak References]'', Python Enhancement Proposal, January 2001.
|