Implementation of reference counting GC (edited)

Source: Internet
Author: User

We talked about GC. There are many items about GC on the Internet. Now let's think about the implementation of simple GC. Reference counting is a simple idea.

Reference count. The main summary is:
It is the only garbage collection algorithm that does not use the root set. This algorithm uses the reference counter to distinguish between a surviving object and an object that is no longer in use. Generally, each object in the heap corresponds to a reference counter. When an object is created and assigned to a variable, the reference counter is set to 1. When an object is assigned to any variable, add 1 to each reference counter. When an object is out of scope (this object is discarded and is no longer used), the reference counter minus 1. Once the reference counter is 0, the object meets the garbage collection condition.
The reference counter-based Garbage Collector runs fast and does not interrupt program execution for a long time. It is suitable for programs that must run in real time. However, the reference counter increases the overhead of program execution because each time an object is assigned to a new variable, the counter is incremented by 1, and every time an existing object has a scope, the counter is reduced by 1.

There are two key points in the method:
1. Allocate addresses and provide pointer operations in the "behind the scenes;
2. manage one or more lists to maintain the Object Memory allocated when the program is running.
There are three key points in implementation:
1. Provide encapsulation of "behind-the-scenes" operations;
2. Information of the maintained object allocation list;
3. An iterator that facilitates search.

Let's take a look at the method first. In short, it is:
Create a list for each object in each scope to maintain information about each object dynamically allocated. This information contains the address of the object and the number of pointers referenced by the address (reference count ). When a new object is successfully allocated with memory, it will be registered in the list and set the reference count to 1. Whenever other pointers point to this object, update the reference count of this object address in the list plus 1. A simple policy is to set the time for garbage collection to take effect when the object operates. When you need to call the destructor, the object address reference count is reduced by 1. If the reference count of the object address is reduced to 0, the object address can be recycled.

Implementation:
In C ++, the overload operator is used to encapsulate the object memory allocation and Object Pointer operations. The result is that the program is basically written in C ++ syntax. Encapsulate information that needs to be saved in the "spam list" into a class and put it in the list as an object instance for ease of management. Provide an iterator -- of course, this is not necessary to facilitate traversing the maintained list.

Here we provide a simple example of code by combining some information:
I. Category introduction:
// ----------- Class gclistinfo -------
Template <class T> // This is the class that encapsulates information in the "spam list ".
Class gclistinfo
{
Public:
Unsigned refcount; // current reference count
T * memptr; // pointer to the allocated space
Bool isarray; // if it points to an array, it is set to true.
Unsigned arraysize; // The array size if it points to a number.
Gclistinfo (T * mptr, unsigned size = 0 );
};
// ----------- Class ITER -------
Template <class T> // iterator
Class ITER
{
T * PTR; // current pointer Value
T * end; // point to the next position of the last element
T * begin; // point to the start of the allocated space
Unsigned length; // sequence length
Public:

...... // Reload and provide STL-compatible Operators

};

// ----------- Class gcptr -------
Template <class T, int size = 0> // encapsulate the operation class
Class gcptr
{
Static list <gclistinfo <t> gclist; // gclist maintains a garbage collection list.
T * ADDR; // The allocated space pointed to by the gcptr pointer.
Bool isarray; // if it points to an array, it is set to true.
Unsigned arraysize; // The array size if it points to a number.
Static bool first; // this parameter is set to true when the first gcptr is created.
// Iterator that returns the gclist pointer Information
Typename list <gclistinfo <t>: iterator findptrinfo (T * PTR );
Public:
// Defines an iterator name for gcptr <t>.
Typedef ITER <t> gciterator;
// A tool function that displays gclist.
Static void showlist ();
// When the program exits, the gclist content is cleared.
Static void Shutdown ();
// Constructor
Gcptr (T * t = NULL );
// Copy the constructor.
Gcptr (const gcptr & ob );
// Destructor.
~ Gcptr ();
// Recycle garbage. Returns true if at least one object is released.
Static bool docollection ();
// Reload the value assignment operator from pointer to gcptr.
T * operator = (T * t );
// Reload the value assignment operators of gcptr and gcptr.
Gcptr & operator = (gcptr & RV );
// Returns an object reference directed to by the current gcptr.
T & operator *();
// Returns the current address.
T * operator-> ();
// Reload []. Return object reference with index I.
T & operator [] (int I );
// Return the ITER of the allocated memory start address.
Typename gciterator begin ();
// Returns the next position of an ITER pointing to the last element of the allocated space.
Typename gciterator end ();
// Obtain the gclist size.
Static int gclistsize ();
};

II. Implementation points:
It is easy to note that the gcptr <t> class is our most important, and it deals directly with users. The maintenance list mentioned above, as well as the release of junk space, are mainly completed through the constructor, destructor, and static member function docollection. The following describes the three functions.
1. Build list:
// Constructor
Template <class T, int size>
Gcptr (T * t = NULL)
{
// Register Shutdown () as the exit function ).
If (gcptr <t, size >:: first ){
: Atexit (shutdown );
}
Gcptr <t, size >:: first = false;
List <gclistinfo <t>: iterator P;
P = This-> findptrinfo (t );
If (P! = Gcptr <t, size >:: gclist. End () // If t already exists in gclist
P-> refcount ++; // increase the ref count.
Else {// recreate
Gclistinfo <t> gcobj (T, size );
Gcptr <t, size >:: gclist. push_front (gcobj );
}
This-> ADDR = T; // obtain the current address.
This-> arraysize = size; // obtain the array size.
If (size> 0)
This-> isarray = true;
Else
This-> isarray = false;
}
This is relatively simple. When a gcptr object is created, it starts to determine whether to create a record in gclist and then information about the address of the target object indicated by the object.

2. Release garbage:
// Gcptr destructor.
Template <class T, int size>
Gcptr <t, size> ::~ Gcptr ()
{
List <gclistinfo <t>: iterator P;
P = This-> findptrinfo (this-> ADDR );
If (p-> refcount)
P-> refcount --; // decrement ref count
// Garbage collection is performed when the pointer leaves the scope. (This is a simple strategy)
Gcptr <t, size >:: docollection ();

}
This was originally the most complicated part of this (timing strategy) and simplified to this (-_-*). That is to say, when a Member has a function scope and needs to be analyzed, garbage collection starts.

3. Garbage collection:
// Recycle garbage. Returns true if at least one object is released.
Template <class T, int size>
Bool gcptr <t, size>: docollection ()
{
Bool memfreed = false; // identifies whether an object is released

List <gclistinfo <t>: iterator P;
Do {
// In gclist, find the pointer that is not pointed.
For (P = gcptr <t, size>: gclist. Begin ();/
P! = Gcptr <t, size >:: gclist. End (); P ++ ){
If (p-> refcount> 0) // useful pointer
Continue;

// Release gcptr if it is not null.
If (p-> memptr ){
If (p-> isarray) {// if it points to an array
Delete [] p-> memptr;
}
Else {
Delete P-> memptr;
}
}

// Remove useless pointers from gclist.
Gcptr <t, size >:: gclist. Remove (* P );
Memfreed = true;

// Search again
Break;
}

} While (P! = Gcptr <t, size >:: gclist. End ());

Return memfreed;
}
This is the garbage collection function called at the end of the destructor. The analysis is quite simple: traverse the gclist repeatedly, find the space where the reference count is 0, and release it. Note that when the constructor registers showdown as the function to close the function, that is, if the gclist is still not empty when the program exits, the function is called directly to free up space.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.