Relationship between garbage collection and strong references, soft references, and phantom references

Source: Internet
Author: User

The Java 2 platform introduces the java. Lang. Ref package, including classes that allow you to reference objects without leaving them in memory. These classes also provide limited interaction with the garbage collector. Peter Haggar analyzes functions and behaviors of softreference, weakreference, and phantomreference classes in this article, and provides some suggestions on the programming style for the use of these classes.
When the java. Lang. Ref package (including softreference, weakreference, and phantomreference classes) is introduced for the first time on the Java 2 platform, its practicality is obviously exaggerated. The classes it contains may be useful, but some limitations of these classes make them not very attractive, and their applications will be particularly limited to solving a specific category of issues.

Garbage collection Overview
The main function of the reference class is to reference objects that can still be recycled by the garbage collector. Before introducing a reference class, we can only use strong reference ). For example, the following line of code shows a strongly referenced OBJ:

Object OBJ = new object ();

OBJ references an object stored in the heap. As long as the OBJ reference still exists, the garbage collector will never release the storage space used to hold the object.

When obj is out of the range or explicitly specified as null, the garbage collector considers that there is no other reference to this object and can collect it. However, you also need to pay attention to the important details: the collection of objects alone does not mean that the garbage collector can recycle it at a specified operation. Due to different garbage collection algorithms, some algorithms analyze objects with shorter lifetime more frequently than older objects with longer lifetime. Therefore, an object that can be collected may never be recycled. This situation may occur if the program ends before the Garbage Collector releases the object. Therefore, in summary, you will never guarantee that the objects available for collection will always be collected by the garbage collector.

This information is very important for you to analyze reference classes. Because garbage collection has a specific nature, the reference classes may not be as useful as you originally thought. However, they are useful for specific problems. Soft reference, weak reference, and phantom reference objects provide three different methods to reference heap objects without interfering with collection. Each referenced object has different behaviors, and their interaction with the garbage collector is also different. In addition, these new reference classes all show more weak references than typical references. In addition, an object in the memory can be referenced by multiple references (strong reference, soft reference, weak reference, or virtual reference. Before further discussion, let's take a look at some terms:

Stronugly reachable: objects that can be accessed through strong references.

Softly reachable: an object that is not highly accessible and can be accessed through soft references.

Weakly reachable: objects that are not strong or soft or accessible through weak references.

Phantomly reachable.

Clear: Set the referent field of the referenced object to null, and declare the object referenced by the reference class in the heap as final.
Softreference class
Softreference is typically used for memory-sensitive high-speed caching. Softreference is used to ensure that all soft references are cleared before the JVM reports insufficient memory when the object is referenced. The key is that the Garbage Collector may (or may not) release software and objects at runtime. Whether the object is released depends on the garbage collector algorithm and the amount of memory available when the garbage collector is running.

Weakreference class
A typical use of the weakreference class is canonicalized mapping ). In addition, for objects with relatively long lifetime and Low Re-creation overhead, weak references are also useful. The key is that if the spam collector encounters a weak object during runtime, The weakreference reference object will be released. However, note that the spam Collector may have to run multiple times to locate and release weak accessible objects.

Phantomreference class
The phantomreference class can only be used to track the forthcoming collection of referenced objects. It can also be used for pre-mortem cleanup. Phantomreference must be used with the referencequeue class. Referencequeue is required because it can act as a notification mechanism. When the Garbage Collector determines that an object is a virtual object, the phantomreference object is placed on its referencequeue. Placing the phantomreference object in the referencequeue is also a notification, indicating that the object referenced by the phantomreference object has ended and can be collected. This allows you to take action just before the memory occupied by the object is recycled.

Interaction between the Garbage Collector and reference
The garbage collector can freely release the memory occupied by objects that are no longer highly accessible. If the spam collector discovers software and objects, the following situations occur:

The referent field of the softreference object is set to null, so that the object does not reference the heap object.

The heap object referenced by softreference is declared as finalizable.

When the finalize () method of the heap object is run and the memory occupied by the object is released, the softreference object is added to its referencequeue (if the latter exists ).
If the spam collector finds weak and accessible objects, the following situations occur:

The referent field of the weakreference object is set to null, so that the object does not reference the heap object.

The heap object referenced by weakreference is declared as finalizable.

When the finalize () method of the heap object is run and the memory occupied by the object is released, the weakreference object is added to its referencequeue (if the latter exists ).
If the spam collector discovers virtual possibilities and objects, the following situations occur:

The heap object referenced by phantomreference is declared as finalizable.

Unlike soft reference and weak reference, phantomreference is added to its referencequeue before the heap object is released. (Remember that all phantomreference objects must be created using the associated referencequeue .) This allows you to take action before the heap object is recycled.
Consider the code in Listing 1. Figure 1 shows the code execution.

Listing 1. sample code using weakreference and referencequeue
// Create a strong reference to an object
Myobject OBJ = new myobject (); // 1

// Create a reference queue
Referencequeue RQ = new referencequeue (); // 2

// Create a weakreference to OBJ and associate our reference queue
Weakreference wR = new weakreference (OBJ, rq); // 3

Figure 1. Object layout after the code of the row/1, // 2 and // 3 in Listing 1 is executed

Figure 1 shows the status of each object after each line of code is executed. Row // 1 creates a myobject object, and row // 2 creates a referencequeue object. Row // 3 creates a weakreference object that references its referenced object myobject and its referencequeue. Note that each object reference (OBJ, RQ, and wr) is strongly referenced. To use these reference classes, you must cancel the strong reference to the myobject object by setting OBJ to null. As mentioned above, if this is not done, the object myobject will never be recycled, and any advantages of the referenced class will be weakened.

Each referenced class has a get () method, while the referencequeue class has a poll () method. The get () method returns a reference to the referenced object. Call get () on phantomreference always returns NULL. This is because phantomreference is only used for tracking and collection. The poll () method returns the referenced object that has been added to the queue. If no object exists in the queue, null is returned. Therefore, the result of calling get () and Poll () after listing 1 may be:

Wr. Get (); // returns reference to myobject
RQ. Poll (); // returns NULL

Now let's assume that the garbage collector is running. Because the myobject object is not released, the get () and Poll () methods will return the same value; OBJ will continue to strongly reference the object. In fact, the object layout remains unchanged, as shown in figure 1. However, consider the following code:

OBJ = NULL;
System. GC (); // run the Collector

After this code is executed, the object layout is shown in 2:

Figure 2. OBJ = NULL; and the Object layout after the spam collector is run

Now, calling get () and Poll () will produce different results:

Wr. Get (); // returns NULL
RQ. Poll (); // returns a reference to the weakreference object

This indicates that the myobject object (its reference was originally carried out by the weakreference object) is no longer available. This means that the Garbage Collector releases the memory occupied by myobject so that the weakreference object can be placed on its referencequeue. In this way, you can know that when the get () method of weakreference or softreference class returns NULL, an object is declared as finalizable and May (but not necessarily) be collected. Weakreference or softreference will be placed on the associated referencequeue only when the heap object ends completely and its memory is recycled. Listing 2 shows a complete runnable program that shows part of these principles. The code itself is quite descriptive. It contains many comments and print statements to help you understand.

List 2. shows the complete program for referencing the class Principle
Import java. Lang. Ref .*;
Class myobject
{
Protected void finalize () throws throwable
{
System. Out. println ("in Finalize method for this object:" +
This );
}
}

Class referenceusage
{
Public static void main (string ARGs [])
{
Hold ();
Release ();
}

Public static void hold ()
{
System. Out. println ("example of incorrectly holding a strong" +
"Reference ");
// Create an object
Myobject OBJ = new myobject ();
System. Out. println ("object is" + OBJ );

// Create a reference queue
Referencequeue RQ = new referencequeue ();

// Create a weakreference to OBJ and associate our reference queue
Weakreference wR = new weakreference (OBJ, rq );

System. Out. println ("the weak reference is" + wr );

// Check to see if it's on the ref queue yet
System. Out. println ("polling the reference queue returns" +
RQ. Poll ());
System. Out. println ("getting the referent from the" +
"Weak reference returns" + Wr. Get ());

System. Out. println ("calling GC ");
System. GC ();
System. Out. println ("polling the reference queue returns" +
RQ. Poll ());
System. Out. println ("getting the referent from the" +
"Weak reference returns" + Wr. Get ());
}

Public static void release ()
{
System. Out. println ("");
System. Out. println ("example of correctly releasing a strong" +
"Reference ");
// Create an object
Myobject OBJ = new myobject ();
System. Out. println ("object is" + OBJ );

// Create a reference queue
Referencequeue RQ = new referencequeue ();

// Create a weakreference to OBJ and associate our reference queue
Weakreference wR = new weakreference (OBJ, rq );

System. Out. println ("the weak reference is" + wr );

// Check to see if it's on the ref queue yet
System. Out. println ("polling the reference queue returns" +
RQ. Poll ());
System. Out. println ("getting the referent from the" +
"Weak reference returns" + Wr. Get ());

System. Out. println ("set the OBJ reference to null and call GC ");
OBJ = NULL;
System. GC ();
System. Out. println ("polling the reference queue returns" +
RQ. Poll ());
System. Out. println ("getting the referent from the" +
"Weak reference returns" + Wr. Get ());
}
}

Purpose and Style
The principle behind these classes is to avoid leaving objects in the memory during application execution. Instead, you reference an object using soft reference, weak reference, or virtual reference, so that the garbage collector can release the object at will. This is useful when you want to minimize the heap memory used by your application in its lifecycle. You must remember that to use these classes, you cannot retain strong references to objects. If you do this, it will waste any of the benefits provided by these classes.

In addition, you must use the correct programming style to check whether the collector has recycled the object before using it. If yes, you must recreate the object first. This process can be completed in different programming styles. Selecting an incorrect style will cause problems. Consider the code style in listing 3 for retrieving referenced objects from weakreference:

Listing 3. retrieving the style of the referenced object
OBJ = Wr. Get ();
If (OBJ = NULL)
{
WR = new weakreference (recreateit (); // 1
OBJ = Wr. Get (); // 2
}
// Code that works with OBJ

After studying this code, see another code style in Listing 4 to retrieve referenced objects from weakreference:

Listing 4. Retrieving another style of referenced objects
OBJ = Wr. Get ();
If (OBJ = NULL)
{
OBJ = recreateit (); // 1
WR = new weakreference (OBJ); // 2
}
// Code that works with OBJ

Compare the two styles to see if you can determine which one is feasible or not. The style shown in listing 3 is not always feasible in all cases, but the style shown in Listing 4 is fine. The reason why the style in listing 3 is not good is that obj is not necessarily a non-null value after the if block's subject ends. Consider what if the Garbage Collector runs after the row // 1 in listing 3 but before the row // 2 is executed. The recreateit () method will re-create the object, but it will be referenced by weakreference rather than strongly referenced. Therefore, if the collector runs before a strong reference is applied to a re-created object in row/2, the object will be lost, and wR. Get () will return null.

Listing 4 does not solve this problem because the row/1 re-creates an object and specifies a strong reference for it. Therefore, if the Garbage Collector runs after the row (but before the row // 2), the object will not be recycled. Then, row // 2 creates a weakreference for obj. After the if block is used, you should set OBJ to null so that the garbage collector can recycle this object to make full use of weak references. Listing 5 shows a complete program that shows the differences between the styles we described just now. (To run the program, there must be a "Temp. fil" file in the running directory.

Listing 5. shows the complete program of the correct and incorrect programming style.
Import java. Io .*;
Import java. Lang. Ref .*;

Class referenceidiom
{
Public static void main (string ARGs []) throws filenotfoundexception
{
Broken ();
Correct ();
}

Public static filereader recreateit () throws filenotfoundexception
{
Return new filereader ("Temp. fil ");
}

Public static void broken () throws filenotfoundexception
{
System. Out. println ("executing method broken ");
Filereader OBJ = recreateit ();
Weakreference wR = new weakreference (OBJ );

System. Out. println ("WR refers to object" + Wr. Get ());

System. Out. println ("now, clear the reference and run GC ");
// Clear the strong reference, then run GC to collect obj.
OBJ = NULL;
System. GC ();

System. Out. println ("WR refers to object" + Wr. Get ());

// Now see if OBJ was collected and recreate it if it was.
OBJ = (filereader) Wr. Get ();
If (OBJ = NULL)
{
System. Out. println ("now, recreate the object and wrap it
In a weakreference ");
WR = new weakreference (recreateit ());
System. GC (); // filereader object is not pinned... there is no
// Strong reference to it. Therefore, the next
// Line can return null.
OBJ = (filereader) Wr. Get ();
}
System. Out. println ("WR refers to object" + Wr. Get ());
}

Public static void correct () throws filenotfoundexception
{
System. Out. println ("");
System. Out. println ("executing method correct ");
Filereader OBJ = recreateit ();
Weakreference wR = new weakreference (OBJ );

System. Out. println ("WR refers to object" + Wr. Get ());

System. Out. println ("now, clear the reference and run GC ");
// Clear the strong reference, then run GC to collect OBJ
OBJ = NULL;
System. GC ();

System. Out. println ("WR refers to object" + Wr. Get ());

// Now see if OBJ was collected and recreate it if it was.
OBJ = (filereader) Wr. Get ();
If (OBJ = NULL)
{
System. Out. println ("now, recreate the object and wrap it
In a weakreference ");
OBJ = recreateit ();
System. GC (); // filereader is pinned, this will not affect
// Anything.
WR = new weakreference (OBJ );
}
System. Out. println ("WR refers to object" + Wr. Get ());
}
}

Summary
If used properly, the reference class is still very useful. However, since the behavior of the garbage collector on which they depend is sometimes unpredictable, their practicality will be affected. Whether they can be effectively used depends on whether the correct programming style is applied. The key is to understand how these classes are implemented and how they are programmed.
========================================================== ========================================================== =

Java objects are in the following states:

  • Created (created)
  • Strong reachable)
  • Invisible)
  • Unreachable)
  • Collected (collected)
  • Finalized)
  • Recycled (deallocated)

Status transition of Java object lifecycle:{Image: img1_objectstatus.jpg | width = 400}Reference object
Three new reference types:

  • Soft reference)
  • Weak reference)
  • Phantom reference)

Strong reachable)
Definition :~ An object is strong reachable if it can be reached by some thread without traversing any reference objects. A newly-created object is strong reachable by the thread that created it .~
Objects in the strongly reachable State will not be recycled under any circumstances.Softly reachable)
Definition :~ An object is softly reachable if it is not stronugly reachable but can be reached by traversing a soft reference .~
Meaning: when the object is not in the strongly accessible state and can be accessed through soft references, it is in the soft accessible state.
When the program applies for memory, the garbage collector determines whether to recycle objects in the soft reachable state. If it decides to recycle an object, the garbage collector will clear all soft references pointing to the object, if any object in other soft accessible state can access this object through strong references, the soft references pointing to these objects will also be cleared. when determining which soft accessible objects are collected, the garbage collector adopts the "Longest UNUSED" principle or "least used" principle. the garbage collector also ensures that all soft references are cleared before the outofmemeryerror is generated.

  • Generate and use a soft reference
// createSoftReference sr = new SoftReference(new SomeObject());// getSomeObject o = (SomeObject) sf.get();// create in a reference queue;ReferenceQueue queue = new ReferenceQueue();SoftReference sr = new SoftReference(new SomeObject(), queue);

Weakly reachable)
Definition :~ An object is weakly reachable if it is neither strongly nor softly reachable but can be reached by traversing a weak reference .~
The garbage collector clears all weak references at a time.Phantomly reachable)
Definition :~ An object is phantomly reachable if it is neither stronugly, softly, nor weakly reachable, It has been finalized, and some phantom Reference refers to it .~
Phantom references cannot be created directly. You must create them by referencing the queue level:

ReferenceQueue queue = new ReferenceQueue();PhantomReference pr = new PhantomReference (new SomeObject(), queue);

You cannot get the object again from phantom reference, PR. get () returns NULL forever. in addition, you must call reference. clear () manually clear phantom references. all about referenceobjects no interwiki reference defined in properties for wiki called '[http'!)]
Reference objects no interwiki reference defined in properties for wiki called '[http'!)]
Reference objects and garbage collection no interwiki reference defined in properties for wiki called '[http'!)]
/[Jike thread/? Soft, weak, and phantom references | http://www-124.ibm.com/pipermail/jikesrvm-core/2003-may/000365.html]

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.