Java 2 Reference Type Guide

xiaoxiao2021-03-06  90

Original: http://www-900.ibm.com/developerWorks/cn/java/j-refs/index.shtml learning how to effectively use SoftReference, Weakreference, and PhantomReference

Level: primary

Peter Haggar (Haggar@us.ibm.com) Senior Software Engineer, IBM Company January 2003

Java 2 platform introduced

Java.lang.ref package, which enables you to reference objects without leaving them in memory. These classes also provide limited interactions with the garbage collection. Peter Haggar is analyzed in this article.

SoftReference,

Weakreference and

The features and behaviors of the PhantomReference class, and some programming styles are given on these classes.

When the Java.lang.Ref package is first introduced in the Java 2 platform (which contains SoftReference, WeakReference, and PhantomReference classes), its practicality is obviously too exaggerated. Its classes that it contain may be useful, but some limitations of these classes make them are not very attractive, and their applications will also be particularly limited to solving a specific type of problem.

The main function of the garbage collection outline reference class is to reference the object that can still be recovered by the garbage collector. We can only use strong references before introducing the reference class. For example, the following line code is displayed to quote OBJ:

Object obj = new object ();

Obj This reference will reference 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 accommodate the object.

When the OBJ is out of range or explicitly specified as NULL, the garbage collector believes that there is no other reference to this object, and it can collect it. However, you also need to pay attention to an important detail: only objects can be collected and not meant to be able to recycle it at a specified run of the garbage collector. Since various garbage collection algorithms are different, some algorithms will analyze the older objects in the survival period more frequently, rather than the older, long-lived objects. Therefore, an object that can be collected may never be recycled. This situation may appear if the program ends before the garbage collector releases the object. Therefore, in summary, you will never guarantee that the available objects will always be collected by the garbage collector.

This information is important for your analysis. Since garbage collection has a specific nature, the reference class may actually be useful to be as useful, despite this, despite this, it is still a useful class for a particular problem. Soft Reference, WEAK Reference and Phantom Reference Objects provide three different ways to reference a heap object without hindering collection. Each reference object has different behaviors, and their interaction between the garbage collector is different. In addition, these new reference classes exhibit a typical stronger reference "more weak" reference form. Moreover, an object in memory can be referenced by multiple references (can be strong reference, soft reference, weak reference or virtual). Let's take a look at some terms before discussing in further discussion:

Strongly and Strongly Reachable: You can access the accessible object. Softly REACHABLE: Not strong and objects, and can be accessed through a soft reference. Weakable and objects: Not strong and objects are not soft and objects, and can be accessed through weak references. Virtual and objects (Phantomly Reachable): Not strong and object, soft and object, is not weak and object, has ended, can be accessed by the object. Clear: Set the reference domain of the reference object to NULL and declare the object referenced in the stack to the end. A typical use of the SoftReference class SoftReference class is to use for memory-sensitive caches. The principle of SoftReference is to ensure that all soft references will be cleared before maintaining the status of the object to the Object. The key is that the garbage collector may (or may not) release soft and objects at runtime. Whether the object is released depends on the amount of memory available to the garbage collector and the amount of memory available when the garbage collector is running.

A typical use of the Weakreference class WeakReference class is a standardized mapping. In addition, weak references are also useful for objects that are relatively long and re-created overhead and re-created overhead. The key is that if the garbage collector is running, it will release the object of WeakReference reference when it comes to the weak and object. However, please note that the garbage collector may have to run multiple times to find and release weak and objects.

The PhantomReference class PhantomReference class can only be used to track collections to be cited objects. Again, it can also be used to perform the pre-Mortem clearance operation. PhantomReference must be used with the ReferenceQueue class. ReferenceQueue is required because it can act as a notification mechanism. When the garbage collector determines an object being a virtual and object, the PhantomReference object is placed on its ReferenceQueue. The PhantomReference object is placed on ReferenceQueue is also a notification, indicating that the object referenced by the PhantomReference object is over, which is available. This allows you to take action before the memory occupied by the object.

Garbage collectors and reference interactive garbage collectors can freely release the memory that is no longer a strong object occupied. If the garbage collector discovers soft and object, the following conditions appear:

The REFERENT domain of the SoftReference object is set to NULL, so that the object will no longer reference the Heap object. The HEAP object referenced by SOFTReference is declared as Finalizable. When the Finalize () method of the HEAP object is running and the memory occupied by the object is released, the SoftReference object is added to its ReferenceQueue (if the latter exists).

If the garbage collector discovers weak and object, the following cases occur:

The REFERENT field of the WeakReference object is set to NULL, so that the object will no longer reference the HEAP object. The Heap object referenced by WeakReference is declared as Finalizable. When the Finalize () method of the HEAP object is running and the memory occupied by the object is released, the WeakReference object is added to its ReferenceQueue (if the latter exists). If the garbage collector discovers the virtual and object, the following conditions will occur:

The Heap object referenced by PhantomReference is declared as Finalizable. Unlike soft references and weak references, PhantomReference is added to its ReferenceQueue before the heap object is released. (Remember, all PhantomReference objects must be created with the associated referenceQueue.) This allows you to take action before you are recycled on a heap.

Consider the code in Listing 1. Figure 1 illustrates the implementation of this code.

Listing 1. Using WeakReference and ReferenceQueue sample code

// Create a strong reason to an Object

MyObject obj = new myObject (); // 1

// Create a Reference Queue

ReferenceQueue rq = new referenceQueue (); // 2

// Create a weakreference to obj and associate ur reason queue

Weakreference WR = New WeakReference (Obj, RQ); // 3

Figure 1. Object layout after executing the code of the Listing 1 Bank // 1, // 2 and // 3

Figure 1 shows the status of each object after each line code execution. Row // 1 Create a MyObject object, and row // 2 Create a ReferenceQueue object. Row // 3 Create a reference to its reference object MyObject's WeakReference object, but also create its ReferenceQueue. Note that each object reference (OBJ, RQ and WR) is strongly referenced. To take advantage of these reference classes, you must cancel the strong reference to myObject objects, and the method is to set the OBJ to NULL. As mentioned earlier, if you don't do this, the object MyObject will never be recycled, and any advantages of the reference class will be weakened.

Each reference class has a get () method, and the ReferenceQueue class has a POLL () method. Get () method Returns a reference to the referenced object. Tune GET () always returns NULL in PhantomReference. This is because PhantomReference is only used to track collections. Poll () method Returns a reference object that has been added to the queue, if there is no object in the queue, it returns NULL. Therefore, the results of the GET () and poll () may be called after executing the list 1.

Wr.get (); // returns reason to myObject

Rq.poll (); // Returns Null

Now we assume that the garbage collector starts running. Since the MyObject object is not released, the GET () and poll () methods will return the same value; OBJ still maintains the object to stronger. In fact, the object layout still has not changed, and the difference shown in Figure 1 is almost. However, please consider the following code:

Obj = null; system.gc (); // Run the Collector

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

Figure 2. Obj = NULL; Object layout after running in the garbage collector

Calling GET () and poll () will now produce different results:

Wr.get (); // Returns Null

Rq.poll (); // returns a reason to the weakreference object

This situation indicates that the MyObject object (the reference to its reference is made 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. This way, you can know that when the Get () method of the WeakReference or SoftReference class returns NULL, there is an object being declared as Finalizable, and may be collected. Weakreference or SoftReference will only be placed on the ReferenceQueue associated with it when the HEAP object is completely over and its memory is recovered. Listing 2 shows a complete running program that shows part of these principles. This code itself is not illustrated, it contains a lot of comments and print statements, which can help you understand.

Listing 2. Display the full program of the reference 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"

"reason");

// Create An Object

MyObject obj = new myObject ();

System.out.println ("Object IS" OBJ);

// Create a Reference Queue

Referencequeue rq = new reasonQueue ();

// Create a weakreference to obj and associate ur reason 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 Reference 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 Reference from THE"

"Weak Reference Returns" Wr.get ());

}

Public static void release ()

{

System.out.println ("");

System.out.Println ("Example of Correctly Releaseing A Strong"

"reason");

// Create An Object

MyObject obj = new myObject ();

System.out.println ("Object IS" OBJ);

// Create a Reference Queue

Referencequeue rq = new reasonQueue ();

// Create a weakreference to obj and associate ur reason 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 Reference 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 Reference from THE"

"Weak Reference Returns" Wr.get ());

}

}

The principle behind these and style is to avoid staying the object in memory during the application execution. Instead, you will reference the object in a soft reference, weak reference or false, so that the garbage collector can freely release the object. This use is very beneficial when you want to minimize the amount of the application used in its life cycle. You must remember that you want to use these classes, you cannot retain strong references to the object. If you do this, you will waste any benefits provided by these classes.

Alternatively, you must use the correct programming style to check if the collector has reclaimed it before using the object. If you have been reclaimed, you must first recreate the object. This process can be done with different programming styles. Choosing the wrong style will result in a problem. Consider the code style from WeakReference retrieved objects from WeakReference: List 3. Retrieve the style of reference 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, check out another code style of retrieve the reference object from WeakReference in Listing 4:

Listing 4. Retrieving another style of the referenced object

Obj = wr.get ();

IF (Obj == Null)

{

Obj = recreateit (); // 1

WR = new weakreference (obj); // 2

}

// Code That Works with Obj

Please compare these two styles to see if you can determine which style must be feasible, which is not necessarily possible. The style reflected in Listing 3 does not necessarily be feasible in all situations, but the style 4 of the list 4 can be. The reason why the style in Listing 3 is not good enough is that the OBJ is not necessarily non-null after the main body of the IF block. Consider thinking if the garbage collector is running after the list of Listing 3 but runs before the line // 2 is executed. The recreateit () method will recreate the object, but it will be referenced by WeakReference instead of strong reference. Therefore, if the collector runs before row // 2 to apply a strong reference to a strong reference on the recreated object, the object will be lost, and Wr.Get () returns NULL.

Listing 4 does not have this problem, because the line // 1 recreates the object and specifies a strong reference for it. Therefore, if the garbage collector is running after the line (but before row // 2), the object will not be recycled. Then, rows // 2 will create WeakReference to OBJ. After using the OBJ after using this IF block, you should set the OBJ to NULL so that the garbage collector can reclaim this object to take full advantage of weak references. Listing 5 shows a complete program that will show the difference between the style we describe. (To run the program, there must be a "temp.fil" file in the run directory.

Listing 5. Display the correct and incorrect programming styles.

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 brroken () 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 review it if it.

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. there, 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 review it if it.

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

// annhes.

WR = new weakreference (obj);

}

System.out.println ("WR Refers to Object" Wr.get ());

}

Summary If you are used, the reference class is still useful. However, since the garbage collector behavior they rely on is sometimes unsatisfactory, its practicality will be affected. Can you use them effectively depends on whether the correct programming style is applied; the key is how these classes are implemented and how they can program them.

转载请注明原文地址:https://www.9cbs.com/read-94881.html

New Post(0)