In-depth discussion of JAVA.LANG.REF package--turn

Source: Internet
Author: User
Tags java se

Overview

Java.lang.ref is a special package in the Java class Library that provides reference classes that are closely related to the Java garbage collector. These reference class objects can point to other objects, but they are different from generic references because their presence does not prevent the Java garbage collector from reclaiming the objects they point to. The benefit is that the messenger can keep a reference to the object being used, while the JVM can still recycle the object when the memory is not available. Therefore, this package is particularly useful for implementing cache-related applications. The package also provides a mechanism for alerting when the "accessibility" of an object changes. Through the introduction and analysis of the package, the reader can deepen the understanding of the package, so as to make better use of the package for development.

Back to top of page

Introduction of JAVA.LANG.REF Package

Let's take a look at the structure of the Java.lang.ref package, 1 shows

Figure 1. JAVA.LANG.REF Package Structure

The various types of inheritance relationships in the package are shown in 2

Figure 2. Java.lang.ref Inheritance relationships for classes in packages:

Reference is an abstract class, and Softreference,weakreference,phantomreference and finalreference are the concrete classes that inherit it.

Next, we will introduce and analyze the characteristics and usages of the strong references and the various virtual references under the Java.lang.ref package respectively.

Back to top of page

Features and usage of strongreference, SoftReference, WeakReference and phantomreference strongreference:

We all know that the objects in the JVM are allocated on the heap, and when the program does not have references to the object, the object can be reclaimed by the garbage collector. The reference referred to here is the variable (such as String, object, ArrayList, etc.) of the object type declared in our general sense, and the variables (such as int, short, long, etc.) that are distinguished from the original data type are also referred to as strong references.

Before we understand virtual references, we typically use strong references to refer to objects. Such as:

Listing 1. Strongreference usage
String tag = new String ("T");

The tag reference here is called a strong reference. Strong references have the following characteristics:

    • A strong reference can directly access the target object.
    • The object that the strong reference points to is not reclaimed by the system at any time.
    • A strong reference can cause a memory leak.

The three kinds of Reference that we're going to talk about are "weak references" compared to strong references, which means that the objects they reference are recycled by the JVM's garbage collector as long as they don't have a strong reference, and the timing and usage of their collection are different. The following are discussed separately.

SoftReference:

SoftReference is the strongest reference in "weak references". SoftReference points to an object that, when no strong reference points to it, stays in memory for a period of time, and the garbage collector decides whether to recycle it based on the usage of the JVM's memory (the degree of memory shortage) and the call of the SoftReference get () method. (later chapters will be elaborated in several experiments)

The specific use is generally through the construction of SoftReference, will need to use weak reference to point to the object wrapped up. When needed, call SoftReference's Get () method to get it. The Get () method of SoftReference returns a strong reference to the object when it is not reclaimed. As follows:

Listing 2. SoftReference usage
softreference<bean> bean = new softreference<bean> (New Bean ("name", ten));  System.out.println (Bean.get ());//"Name:10"
Reference type get target Object mode garbage Collection Conditions whether memory leaks are possible
Strong references Call directly Do not recycle possible
Soft references Depending on the memory of the recovery No way
Weak references Through the Get () method Recycle Forever No way
Virtual reference Cannot get Do not recycle possible

type whether to throw an exception Sample Code Run Results
Strongreference Throw exception See Listing 6 Exception in thread "main" Java.lang.OutOfMemoryError:Java heap space
SoftReference Does not throw an exception, the previous reference automatically empties and returns null See listing 7 Null
WeakReference Ditto See Listing 8 Null
Phantomreference Throw exception See Listing 9 Exception in thread "main" Java.lang.OutOfMemoryError:Java heap space

Back to top of page

Finalreference and Finzlizer

Finalreference as a java.lang.ref in a public access to the class, and what kind of role? As his subclass, what role does Finalizer play in the garbage collection mechanism?

In fact, Finalreference represents a strong reference in Java, such as this code:

Bean bean = new Bean ();

During the implementation of the virtual machine, the Finalreference class is actually used to refer to it. Finalizer, in addition to being an implementation class, implements a Finalizerthread in the virtual machine so that the virtual machine can implement memory cleanup after all strong references are lifted.

Let's take a look at how Finalizer works. First, by declaring Finalizerthread and instantiating the thread, set it to the daemon thread, and then join the system thread.

Listing 11
static {         Threadgroup TG = Thread.CurrentThread (). Getthreadgroup ();         for (Threadgroup TGN = TG;              TGN! = null;              TG = tgn, TGN = Tg.getparent ());  Thread finalizer = new Finalizerthread (TG);  Finalizer.setpriority (thread.max_priority-2);  Finalizer.setdaemon (true);  Finalizer.start ();  }

During GC, when a strong reference is released, the object that is tagged by the system garbage collector is added to the Referencequeue in the Finalizer object and called Finalizer.runfinalizer () to execute the object's Finalize method.

Listing 12
private void Runfinalizer () {  synchronized (this) {     if (hasbeenfinalized ()) return;     Remove ();  try {     Object Finalizee = This.get ();     if (Finalizee! = NULL &&! ( Finalizee instanceof Java.lang.Enum)) {  invokefinalizemethod (Finalizee);  Note that there is a need to empty the slot in the stack that contains the variable,                    * * To reduce the illusion that the variable was not recycled due to a conservative GC implementation */  Finalizee = null;}  } catch (Throwable x) {}  super.clear ();  }

Note that the Invokefinalizemethod called by the tag is the native method, and since the Finalize method is declared as protected in the Object class, it must be called by the native method. The garbage collector then cleans up the memory by setting the local strong reference to NULL.

As you can see, in this way, Java will have four types of reference objects: Soft Reference (SoftReference), weak reference (WeakReference), strong reference (finalreference), virtual reference (phantomreference) Treated equally, and in the garbage collector for unified scheduling and management.

Back to top of page

Performance and analysis on different Java virtual machines

Let's review the performance of the four reference types and the performance of the garbage collector when it recycles the cleanup memory.

    1. Soft Reference (SoftReference), the reference type behaves as if the memory is nearing full load, or if the call to the object by the Softreference.get () method does not occur for a period of time, the garbage collector cleans up the object. The soft Reference object is added to the Referencequeue before the object's Finalize method is run.
    2. Weak reference (WeakReference), a reference type that behaves as if the system garbage collector starts to recycle, the reference to that object is reclaimed immediately. As with soft references, weak references also add weak reference objects to Referencequeue before the Finalize method of the object is run.
    3. Strong references (finalreference), which are the most commonly used reference types. The JVM system uses Finalizer to manage each strongly referenced object and to add referencequeue when it is marked for cleanup, and invokes the Finalize () method of the object one at a time.
    4. Virtual reference (Phantomreference), which is one of the most unreal reference types. The object referenced by the virtual reference cannot be returned again, no matter where. Virtual references when the system garbage collector starts to reclaim objects, the Finalize () method is called directly, but it is not immediately added to the recycle queue. Only when the real object is cleared by the GC will it be added to the Reference queue.

Here are two more typical JVM environments, Oracle Java SE6 and IBM JDK 6. The following test code is used:

Listing 13. Class Reftestobj
public class Reftestobj {  private int id;  public int getId () {  return ID;  }  public void setId (int id) {  this.id = ID;  }  @Override public  int hashcode () {  return Super.hashcode ();  }  @Override public  String toString () {  return super.tostring () + "[id=" + This.id + "]";  }  @Override  protected void Finalize () {  System.out.println ("Object [" + this.hashcode () + "] [id=" + This.id + "] Come into Finalize ");  try {  super.finalize ();  } catch (Throwable e) {  e.printstacktrace ();}}  }
Listing 14. Class Refmainthread
 Import java.lang.ref.PhantomReference;  Import java.lang.ref.Reference;  Import Java.lang.ref.ReferenceQueue;  Import java.lang.ref.SoftReference;  Import java.lang.ref.WeakReference; public class Refmainthread {public static void main (string[] args) {//create three different reference types required objects Reftestobj Softref = new Reftes  Tobj ();  Reftestobj weakRef = new Reftestobj ();  Reftestobj phanref = new Reftestobj ();  Softref.setid (1);  Weakref.setid (2);  Phanref.setid (3);  referencequeue<reftestobj> softrefqueue = new referencequeue<reftestobj> ();  referencequeue<reftestobj> weakrefqueue = new referencequeue<reftestobj> ();  referencequeue<reftestobj> phanrefqueue = new referencequeue<reftestobj> ();  softreference<reftestobj> softrefobj = new Softreference<reftestobj> (Softref, softRefQueue);  weakreference<reftestobj> weakrefobj = new Weakreference<reftestobj> (WeakRef, weakrefqueue); phantomreference<reftestobj> phanrefobj = new PhantomreferEnce<reftestobj> (Phanref, phanrefqueue);  Print (softrefobj) three objects normally referenced by printing;  Print (weakrefobj);  Print (phanrefobj);  Empties the object softref = null;  WeakRef = null;  Phanref = null; The print reference queue and the Get () method can fetch the object itself if (softrefobj! = null) {System.out.println ("Soft Reference object Run Get ():" + softrefobj  . get ());  System.out.println ("Check soft queue:" + softrefqueue.poll ());  if (weakrefobj! = null) {System.out.println ("Weak Reference Object Run Get ():" + weakrefobj.get ());  System.out.println ("Check weak queue:" + weakrefqueue.poll ());  if (phanrefobj! = null) {System.out.println ("Phantom Reference Object Run Get ():" + phanrefobj.get ());  System.out.println ("Check Phantom queue:" + phanrefqueue.poll ());  }//start to perform garbage collection System.GC ();  System.runfinalization (); Checks whether the queue has been joined to the queue, whether it can also retrieve the object if (softrefobj! = null) {System.out.println ("Soft Reference object Run Get ():" + SOFTREFOBJ.G  ET ());  System.out.println ("Check soft queue:" + softrefqueue.poll ()); } if (Weakrefobj! = Null) {System.out.println ("Weak Reference Object Run Get ():" + weakrefobj.get ());  System.out.println ("Check weak queue:" + weakrefqueue.poll ());  if (phanrefobj! = null) {System.out.println ("Phantom Reference Object Run Get ():" + phanrefobj.get ());  System.out.println ("Check Phantom queue:" + phanrefqueue.poll ()); }//For virtual reference objects, after multiple GC, will not be added to the queue to reference<  Extends reftestobj> Mynewphan = null;  int refcount = 1;  while (Mynewphan = = null) {Mynewphan = Phanrefqueue.poll ();  System.GC ();  System.runfinalization ();  if (Mynewphan! = null) {System.out.println ("Check Phantom queue:" + Mynewphan);  System.out.println ("Count for" + RefCount + "Times");  Break  } RefCount + +;  }} public static void print (reference<reftestobj> ref) {Reftestobj obj = Ref.get (); System.out.println ("The Reference is" + ref.tostring () + "and with Object" + obj + "which is" + (obj = = null?)  "NULL": "NOT Null")); }  }

By executing the refmainthread, we can clearly see the objects being queued in memory and the order and process of calling the Finalize method based on the printed results.

In order to test different JVM environments and eliminate the impression of other factors, this example uses a background environment of Windows2003 32bit JVM.

The environment was first tested for Oracle Java SE 6 Update 23 with the following results:

Listing 15. Test results under Oracle Java SE 6 Update 23
 The Reference is [email protected] and with Object [email protected][id=1] which is n OT null the Reference is [email protected], and with Object [email protected][id=2] which was not null the Refe Rence is [email protected] and with object null which is null Soft Reference object Run Get (): [email protected]  [Id=1] Check soft queue:null Weak Reference Object Run Get (): [email protected][id=2] Check Weak queue:null Phantom refere nCE object Run get (): null Check Phantom Queue:null Object [27744459][id=3] come into finalize Object [21174459][id=2] C ome into finalize Soft Reference Object run Get (): [email protected][id=1] Check Soft queue:null Weak Reference Obj ECT Run get (): null check weak queue:[email protected] Phantom Reference Object Run get (): null check Phantom queue: Null Check Phantom queue:[email protected] Count for 2 times 

As you can see, when a system recycle is run, the virtual and weak references are recycled, and the soft references remain intact due to memory not being tight. Weak references are immediately queued, while virtual references are queued after a two-time loop of manually invoking the GC. Second, the environment used is IBM JDK 6 and the results are as follows:

Listing 16. Test results under IBM JDK 6
 The Reference is [email protected] and with Object [email protected][id=1] which is n OT null the Reference is [email protected], and with Object [email protected][id=2] which was not null the Refe Rence is [email protected] and with object null which is null Soft Reference object Run Get (): [email protected ][id=1] Check soft queue:null Weak Reference Object Run Get (): [email protected][id=2] Check Weak queue:null phant Om Reference object Run get (): null Check Phantom Queue:null Object [958544162][id=3] come into finalize Object [9584130 88][id=2] come into finalize Soft Reference Object run Get (): [email protected][id=1] Check Soft queue:null Weak Re Ference Object Run get (): null check weak queue:[email protected] Phantom Reference Object Run get (): null check Pha Ntom queue:null Object [958282014][id=1] come into finalize ..... 

The program runs here into an infinite loop and must be manually terminated. Two copies of the results can be seen, when the system garbage collection is running multiple times, the IBM JVM adds a soft reference to the Recycle queue and runs its Finalize method. In addition, virtual references are not added to the queue even after a lot of system garbage collection. I don't know if this is a small BUG in the IBM JVM.

Conclusion
    • The performance of the Oracle JVM in SoftReference meets specifications and is only recycled when memory is low. The IBM JVM's strategy is even more aggressive, and it's worth noting that the memory is still plentiful.
    • The performance of the Oracle JVM in phantomreference satisfies the specification, and several GC implementations are added to the Queue after finalize. The IBM JVM has never been added to the Queue causing a dead loop. So when you use Phantomreference, you can consider whether the use of different JVMs is the result of a similar situation.

Back to top of page

Summary

In this paper, the use of Java.lang.ref package is introduced in detail, and the performance of non-homogeneous in the package is analyzed with experiments. At the same time, the performance of the package on different Java virtual machines is analyzed deeply.

Original: http://www.ibm.com/developerworks/cn/java/j-lo-langref/

In-depth discussion of JAVA.LANG.REF package--turn

Related Article

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.