Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Reference counting
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Examples of use== ===Garbage collection=== As a collection algorithm, reference counting tracks, for each object, a count of the number of [[reference (computer science)|reference]]s to it held by other objects. If an object's reference count reaches zero, the object has become inaccessible, and can be destroyed. When an object is destroyed, any objects referenced by that object also have their reference counts decreased. Because of this, removing a single reference can potentially lead to a large number of objects being freed. A common modification allows reference counting to be made incremental: instead of destroying an object as soon as its reference count becomes zero, it is added to a list of unreferenced objects, and periodically (or as needed) one or more items from this list are destroyed. Simple reference counts require frequent updates. Whenever a reference is destroyed or overwritten, the reference count of the object it references is decremented, and whenever one is created or copied, the reference count of the object it references is incremented. Reference counting is also used in file systems and distributed systems, where full non-incremental tracing garbage collection is too time-consuming because of the size of the object graph and slow access speed.<ref>{{cite journal|doi=10.1145/3156818|title=A Study on Garbage Collection Algorithms for Big Data Environments|journal=ACM Computing Surveys|volume=51|pages=1β35|year=2018|last1=Bruno|first1=Rodrigo|last2=Ferreira|first2=Paulo|s2cid=21388487}}</ref> ===Component Object Model=== Microsoft's [[Component Object Model]] (COM) and [[Windows Runtime|WinRT]] makes pervasive use of reference counting. In fact, two of the three methods that all COM objects must provide (in the [[IUnknown]] interface) increment or decrement the reference count. Much of the [[Windows Shell]] and many Windows applications (including [[Microsoft Internet Explorer|MS Internet Explorer]], [[Microsoft Office|MS Office]], and countless third-party products) are built on COM, demonstrating the viability of reference counting in large-scale systems.{{Citation needed|date=October 2022}} One primary motivation for reference counting in COM is to enable interoperability across different programming languages and runtime systems. A client need only know how to invoke object methods in order to manage object life cycle; thus, the client is completely abstracted from whatever memory allocator the implementation of the COM object uses. As a typical example, a [[Visual Basic]] program using a COM object is agnostic towards whether that object was allocated (and must later be deallocated) by a C++ allocator or another Visual Basic component. ===C++=== C++ does not perform reference-counting by default, fulfilling its philosophy of not adding functionality that might incur overheads where the user has not explicitly requested it. Objects that are shared but not owned can be accessed via a reference, raw pointer, or [[Iterator (C++)|iterator]] (a conceptual generalisation of pointers). However, by the same token, C++ provides native ways for users to opt-into such functionality: [[C++11]] provides reference counted [[smart pointers]], via the [[Shared ptr|{{code|std::shared_ptr}}]] class, enabling automatic shared memory-management of dynamically allocated objects. Programmers can use this in conjunction with [[weak pointer]]s (via [[Shared ptr|{{code|std::weak_ptr}}]]) to break cyclic dependencies. Objects that are dynamically allocated but not intended to be shared can have their lifetime automatically managed using a [[Shared ptr|{{code|std::unique_ptr}}]]. In addition, [[Move semantics|C++11's move semantics]] further reduce the extent to which reference counts need to be modified by removing the deep copy normally used when a function returns an object, as it allows for a simple copy of the pointer of said object. ===Cocoa (Objective-C)=== {{See also|Automatic Reference Counting}} Apple's [[Cocoa (API)|Cocoa]] and [[Cocoa Touch]] frameworks (and related frameworks, such as [[Core Foundation]]) use manual reference counting, much like [[Component Object Model|COM]]. Traditionally this was accomplished by the programmer manually sending <code>retain</code> and <code>release</code> messages to objects, but [[Automatic Reference Counting]], a [[Clang]] compiler feature that automatically inserts these messages as needed, was added in [[iOS (Apple)|iOS]] 5<ref>[https://developer.apple.com/technologies/ios5/] {{webarchive|url=https://web.archive.org/web/20110609033837/http://developer.apple.com/technologies/ios5/|date=9 June 2011}}</ref> and [[Mac OS X 10.7]].<ref>{{cite web|url=https://developer.apple.com/library/mac/#releasenotes/MacOSX/WhatsNewInOSX/Articles/MacOSX10_7.html#//apple_ref/doc/uid/TP40010355-SW62 |title=Mac Developer Library |publisher=Developer.apple.com |access-date=2015-12-17}}</ref> [[Mac OS X 10.5]] introduced a tracing garbage collector as an alternative to reference counting, but it was deprecated in [[OS X 10.8]] and removed from the Objective-C [[runtime library]] in [[macOS Sierra]].<ref>{{Cite web|url=https://arstechnica.com/apple/2012/07/os-x-10-8/17/#objective-c-enhancements|title=OS X 10.8 Mountain Lion: the Ars Technica review|last=Siracusa|first=John|date=25 July 2012|at=At section "Objective-C enhancements"|access-date=17 November 2016|work=Ars Technica}}</ref><ref>{{Cite web|url=https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html|title=Xcode 8 Release Notes|date=27 October 2016|website=Apple Developer|access-date=19 March 2017|archive-url=https://web.archive.org/web/20170319065518/https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html|archive-date=19 March 2017}}</ref> [[iOS]] has never supported a tracing garbage collector. ===Delphi=== <!-- this needs a rewrite it takes no account whatsoever of the history of the language! [[User:Plugwash|Plugwash]] 02:00, 24 June 2005 (UTC)--> [[Delphi (programming language)|Delphi]] is mostly not a garbage collected language, in that user-defined types must still be manually allocated and deallocated; however, it does provide automatic collection using reference counting for a few built-in types, such as strings, [[dynamic array]]s, and interfaces<!--i'd hardly call interfaces a built in type [[User:Plugwash|Plugwash]] 02:00, 24 June 2005 (UTC)-->, for ease of use and to simplify the generic database functionality. It is up to the programmer to decide whether to use the built-in types; Delphi programmers have complete access to low-level memory management like in C/C++. So all potential cost of Delphi's reference counting can, if desired, be easily circumvented. Some of the reasons reference counting may have been preferred to other forms of garbage collection in Delphi include: * The general benefits of reference counting, such as prompt collection. * Cycles either cannot occur or do not occur in practice because none of the garbage-collected built-in types are recursive. (using interfaces one could create such scenario, but that is not common usage) * The overhead in code size required for reference counting is very small (on native x86, typically a single LOCK INC, LOCK DEC or LOCK XADD instruction, which ensures atomicity in any environment), and no separate thread of control is needed for collection as would be needed for a tracing garbage collector. * Many instances of the most commonly used garbage-collected type, the string, have a short lifetime, since they are typically intermediate values in string manipulation. A lot of local string usage could be optimized away, but the compiler currently doesn't do it. * The reference count of a string is checked before mutating a string. This allows reference count 1 strings to be mutated directly whilst higher reference count strings are copied before mutation. This allows the general behaviour of old style pascal strings to be preserved whilst eliminating the cost of copying the string on every assignment. * Because garbage-collection is only done on built-in types, reference counting can be efficiently integrated into the library routines used to manipulate each datatype, keeping the overhead needed for updating of reference counts low. Moreover, a lot of the runtime library is in hand-optimized assembler. * The string type can be cast to a pointer to char, and high performance operations can be performed that way. This is important since both Delphi and FPC implement their RTL in Pascal. Various other automated types have such casting options. ===GObject=== The [[GObject]] object-oriented programming framework implements reference counting on its base types, including [[weak reference]]s. Reference incrementing and decrementing uses [[atomic operation]]s for thread safety. A significant amount of the work in writing bindings to GObject from high-level languages lies in adapting GObject reference counting to work with the language's own memory management system. The [[Vala (programming language)|Vala programming language]] uses GObject reference counting as its primary garbage collection system, along with copy-heavy string handling.<ref>{{cite web|url=https://wiki.gnome.org/Projects/Vala/ReferenceHandling |title=Projects/Vala/ReferenceHandling - GNOME Wiki! |publisher=GNOME |date=2015-05-25 |access-date=2015-12-17}}</ref> ===Perl=== [[Perl]] also uses reference counting, without any special handling of circular references, although (as in Cocoa and C++ above), Perl does support weak references, which allows programmers to avoid creating a cycle. ===PHP=== [[PHP]] uses a reference counting mechanism for its internal variable management.<ref>{{Cite web|title=PHP: Reference Counting Basics - Manual|url=https://www.php.net/manual/en/features.gc.refcounting-basics.php|access-date=2020-10-01|website=www.php.net}}</ref> Since PHP 5.3, it implements the algorithm from Bacon's above mentioned paper. PHP allows you to turn on and off the cycle collection with user-level functions. It also allows you to manually force the purging mechanism to be run. ===Python=== [[Python (programming language)|Python]] also uses reference counting and offers cycle detection as well (and can reclaim reference cycles).<ref>{{cite web|url=https://docs.python.org/extending/extending.html#reference-counts |title=1. Extending Python with C or C++ β Python 2.7.11 documentation |publisher=Docs.python.org |date=2015-12-05 |access-date=2015-12-17}}</ref> ===Rust=== Like other low-level languages, [[Rust (programming language)|Rust]] does not provide reference counting by default. Instead, any constructed type will be [[Destructor (computer programming)|dropped]] when it falls out of scope. When a programmer needs to define the scope of a constructed type, they often use lifetimes. However, the language also offers various alternatives to complex forms of memory management. Reference counting functionality is provided by the <code>Rc</code> and <code>Arc</code> types, which are non-atomic and atomic respectively. For example, the type <code>Rc<T></code> provides shared ownership of a value of type <code>T</code>, allocated on the heap for multiple references to its data.<ref>{{cite web |title=std::rc - Rust |url=https://doc.rust-lang.org/std/rc/ |access-date=2 November 2020 |website=doc.rust-lang.org}}</ref> <syntaxhighlight lang="rust"> use std::rc::Rc; struct Cat { color: String, } fn main() { let cat = Cat { color: "black".to_string() }; let cat = Rc::new(cat); } </syntaxhighlight>Using these constructs allows programmers to avoid lifetimes for a small runtime cost. Both reference counters keep track of the number of owners, as they must drop themselves when no owners remain. One noteworthy facet of these types is related to their usage as a shared reference. In Rust, shared references cannot mutate their held data, so <code>Rc</code> often comes bundled with <code>Cell</code>, and <code>Arc</code> with <code>Mutex</code>, in contexts where interior mutability is necessary. Interior mutability without <code>UnsafeCell</code> has performance costs, too, so, for maximum performance, some applications may call for additional complexity.<ref>{{Cite web |date=21 July 2022 |title=The Rust Reference |url=https://doc.rust-lang.org/reference/interior-mutability.html |url-status=live |archive-url=https://web.archive.org/web/20240324062327/https://doc.rust-lang.org/reference/types/pointer.html#shared-references- |archive-date=24 March 2024 |access-date=22 April 2024 |at=Interior Mutability}}</ref> ===Squirrel=== [[Squirrel programming language|Squirrel]] uses reference counting with cycle detection. This tiny language is relatively unknown outside the video game industry; however, it is a concrete example of how reference counting can be practical and efficient (especially in realtime environments).{{Citation needed|date=April 2009}} === Swift === [[Swift (programming language)|Swift]] uses reference counting to track and manage the memory of class instances, and provides the <code>weak</code> keyword for creating weak references. Instances of [[value type and reference type|value types]] do not use reference counting.<ref>{{Cite web |title=Documentation |url=https://docs.swift.org/swift-book/documentation/the-swift-programming-language/automaticreferencecounting/ |access-date=2023-12-06 |website=docs.swift.org}}</ref> ===Tcl=== [[Tcl]] 8 uses reference counting for memory management of values (Tcl Obj [[struct]]s). Since Tcl's values are immutable, reference cycles are impossible to form and no cycle detection scheme is needed. Operations that would replace a value with a modified copy are generally optimized to instead modify the original when its reference count indicates that it is not shared. The references are counted at a data structure level, so the problems with very frequent updates discussed above do not arise. === Xojo === [[Xojo]] also uses reference counting, without any special handling of circular references, although (as in Cocoa and C++ above), Xojo does support weak references, which allows programmers to avoid creating a cycle. ===File systems=== Many file systems maintain reference counts to any particular block or file, for example the [[inode]] ''link count'' on [[Unix filesystem|Unix-style file systems]], which are usually known as [[hard links]]. When the count reaches zero, the file can be safely deallocated. While references can still be made from [[directory (file systems)|directories]], some Unixes only allow references from live processes, and there can be files that exist outside the file system hierarchy.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)