- 浏览: 793769 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (651)
- Java (39)
- Java 初学者小问题 (66)
- 设计模式 (7)
- 项目管理 (3)
- 数据库 (1)
- 算法 (2)
- Java practices (6)
- Effective Java2读书笔记 (78)
- Linux (2)
- programming ruby 读书笔记 (5)
- Core Java Ninth Edition Volume I 读书笔记 (15)
- Pro Git 读书笔记 (12)
- Git (3)
- Maven in Action 读书笔记 (20)
- Web (12)
- 非技术类书籍 (11)
- 电影 (40)
- Web Cache (1)
- jquery (0)
- 历史 (4)
- Dive Into HTML5 读书笔记 (13)
- 三国演义小学毕业考 (79)
- 高效能人士的7个习惯 读书笔记 (12)
- Java Performance 读书笔记 (3)
- Protocol Buffer 学习笔记 (6)
- Mongo DB 学习笔记 (7)
- Morphia 学习笔记 (7)
- Algorithms -- Princeton 学习笔记 (13)
- String研究 (10)
- Hadoop: The Definitive Guide 读书笔记 (3)
- Java与模式读书笔记 (5)
- Date研究 (3)
- The Roman Empire 听课笔记 (4)
- Algorithms -- Standford 学习笔记 (16)
- Core Java Ninth Edition Volume II 读书笔记 (9)
- Thinking in Java 4th Edition 读书笔记 (21)
- Node : Up and Running 学习笔记 (5)
- Eloquent Javascript (8)
- Smashing Node.js 读书笔记 (1)
- Algorithms II -- Standford 学习笔记 (19)
- Algorithm II -- Princeton 学习笔记 (14)
- 网络安全 (2)
- Javascript (4)
- 正则表达式 (1)
- JAVA 7/8 (15)
- JVM (10)
- NodeJS (1)
- 鸟哥的linux私房菜读书笔记 (14)
- Web Service (1)
- The art of programming (9)
- Introduction to Algorithm 读书笔记 (4)
- Java 源码阅读 (0)
- Spring in Action 读书笔记 (2)
- Java Network Programming 读书笔记 (2)
最新评论
-
心存高远:
谢谢作者分享,刚好看到这里不太明白,现在茅塞顿开。不过runt ...
关于 Maven的传递依赖的理解 -
sxlkk:
851228082 写道甚至在某次技术会议现场遇到《Maven ...
关于 Maven的传递依赖的理解 -
851228082:
851228082 写道a----compile----b-- ...
第五章 坐标和依赖 -
851228082:
a----compile----b-----provided- ...
第五章 坐标和依赖 -
851228082:
甚至在某次技术会议现场遇到《Maven in action》的 ...
关于 Maven的传递依赖的理解
When the java.lang.ref
package, which includes the SoftReference
, WeakReference
, and PhantomReference
classes, was first introduced in the Java 2 platform, its usefulness was arguably over-hyped. The classes it contains can be useful, but they have certain limitations that narrow their appeal and make their application very specific to a defined set of problems.
The main feature of the reference classes is the ability to refer to an object that can still be reclaimed by the garbage collector. Before the reference classes were introduced, only strong references were available. For example, the following line of code shows a strong reference, obj
:
Object obj = new Object(); |
The reference obj
refers to an object stored in the heap. As long as the obj
reference exists, the garbage collector will never free the storage used to hold the object.
When obj
goes out of scope or is explicitly assigned to null
, the object is available for collection, assuming there are no other references to it. However, an important detail to note is that just because an object is available for collection does not mean it will be reclaimed by a given run of the garbage collector. Because garbage collection algorithms vary, some algorithms analyze older, longer-lived objects less frequently than short-lived objects. Thus, an object that is available for collection may never be reclaimed. This can occur if the program ends prior to the garbage collector freeing the object. Therefore, the bottom line is that you can never guarantee that an available object will ever be collected by the garbage collector.
This information is important as you analyze the reference classes. They are useful classes for specific problems, although, due to the nature of garbage collection, they might not prove as useful as you originally thought. Soft, weak, and phantom reference objects offer three different ways to refer to a heap object without preventing its collection. Each type of reference object has different behaviors, and their interaction with the garbage collector varies. In addition, the new reference classes all represent a "weaker" form of a reference than the typical strong reference. Furthermore, an object in memory can be referenced by multiple references that could be strong, soft, weak, or phantom. Before proceeding further, let's look at some terminology:
-
Strongly reachable: An object that can be accessed by a strong reference.
-
Softly reachable: An object that is not strongly reachable and can be accessed through a soft reference.
-
Weakly reachable: An object that is not strongly or softly reachable and can be accessed through a weak reference.
-
Phantomly reachable: An object that is not strongly, softly, or weakly reachable, has been finalized, and can be accessed through a phantom reference.
-
Clear: Setting the reference object's referent field to
null
and declaring the object in the heap that the reference class referred to as finalizable.
A typical use of the SoftReference
class is for a memory-sensitive cache. The idea of a SoftReference
is that you hold a reference to an object with the guarantee that all of your soft references will be cleared before the JVM reports an out-of-memory condition. The key point is that when the garbage collector runs, it may or may not free an object that is softly reachable. Whether the object is freed depends on the algorithm of the garbage collector as well as the amount of memory available while the collector is running.
A typical use of the WeakReference
class is for canonicalized mappings. In addition, weak references are useful for objects that would otherwise live for a long time and are also inexpensive to re-create. The key point is that when the garbage collector runs, if it encounters a weakly reachable object, it will free the object the WeakReference
refers to. Note, however, that it may take multiple runs of the garbage collector before it finds and frees a weakly reachable object.
The PhantomReference
class is useful only to track the impending collection of the referring object. As such, it can be used to perform pre-mortem cleanup operations. A PhantomReference
must be used with the ReferenceQueue
class. The ReferenceQueue
is required because it serves as the mechanism of notification. When the garbage collector determines an object is phantomly reachable, the PhantomReference
object is placed on its ReferenceQueue
. The placing of the PhantomReference
object on the ReferenceQueue
is your notification that the object the PhantomReference
object referred to has been finalized and is ready to be collected. This allows you to take action just prior to the object memory being reclaimed.
Garbage collector and reference interaction
Each time the garbage collector runs, it optionally frees object memory that is no longer strongly reachable. If the garbage collector discovers an object that is softly reachable, the following occurs:
- The
SoftReference
object's referent field is set tonull
, thereby making it not refer to theheap
object any longer.
- The
heap
object that had been referenced by theSoftReference
is declaredfinalizable
.
- When the
heap
object'sfinalize()
method is run and its memory freed, theSoftReference
object is added to itsReferenceQueue
, if it exists.
If the garbage collector discovers an object that is weakly reachable, the following occurs:
- The
WeakReference
object's referent field is set tonull
, thereby making it not refer to theheap
object any longer.
- The
heap
object that had been referenced by theWeakReference
is declaredfinalizable
.
- When the
heap
object'sfinalize()
method is run and its memory freed, theWeakReference
object is added to itsReferenceQueue
, if it exists.
If the garbage collector discovers an object that is phantomly reachable, the following occurs:
- The
heap
object that is referenced by thePhantomReference
is declaredfinalizable
.
- Unlike soft and weak references, the
PhantomReference
is added to itsReferenceQueue
before the heap object is freed. (Remember, allPhantomReference
objects must be created with an associatedReferenceQueue
.) This allows for action to be taken before the heap object is reclaimed.
Consider the code in Listing 1. Figure 1 illustrates the execution of this code.
//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 executing lines //1, //2, and //3 of code in Listing 1
Figure 1 shows the state of the objects after each line of code executes. Line //1 creates the object MyObject
, while line //2 creates the ReferenceQueue
object. Line //3 creates the WeakReference
object that refers to its referent, MyObject
, and its ReferenceQueue
. Note that each object reference, obj
, rq
, and wr
, are all strong references. To take advantage of these reference classes, you must break the strong reference to the MyObject
object by setting obj
to null
. Recall that if you do not do this, object MyObject
will never be reclaimed, mitigating any benefit of the reference classes.
Each of the reference classes has a get()
method, and the ReferenceQueue
class has a poll()
method. The get()
method returns the reference to the referent object. Calling get()
on a PhantomReference
always returns null
. This is because PhantomReference
s are only used to track collection. The poll()
method returns the reference object that has been added to the queue, and null
if nothing is on the queue. Therefore, the result of calling get()
and poll()
after the execution of Listing 1 would be:
wr.get(); //returns reference to MyObject rq.poll(); //returns null |
Now, assume the garbage collector runs. The get()
and poll()
methods return the same values because the MyObject
object is not freed; obj
still maintains a strong reference to it. In fact, the object layout remains unchanged and looks like Figure 1. However, consider this code:
obj = null; System.gc(); //run the collector |
After this code executes, the object layout is as depicted in Figure 2:
Figure 2. Object layout after obj = null; and garbage collector is run
Now, calling get()
and poll()
yields different results:
wr.get(); //returns null rq.poll(); //returns a reference to the WeakReference object |
This situation indicates that the MyObject
object, whose reference was originally held by the WeakReference
object, is no longer available. This means that the garbage collector freed the memory for MyObject
, enabling the WeakReference
object to be placed on its ReferenceQueue
. Therefore, you know that an object has been declared finalizable
and possibly, but not necessarily, collected, when the get()
method of the WeakReference
or SoftReference
class returns null
. Only when finalization is completed and the heap
object's memory is collected is the WeakReference
or SoftReference
placed on its associated ReferenceQueue
. Listing 2 shows a full working program demonstrating some of these principles. The code is relatively self-explanatory with many comments and print statements to aid in its understanding.
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()); } } |
The idea behind these classes is to avoid pinning an object in memory for the duration of the application. Instead, you softly, weakly, or phantomly refer to an object, allowing the garbage collector to optionally free it. This usage can be beneficial when you want to minimize the amount of heap memory an application uses over its lifetime. You must remember that to make use of these classes you cannot maintain a strong reference to the object. If you do, you waste any benefit the classes offer.
In addition, you must use the correct programming idiom to check if the collector has reclaimed the object before using it, and if it has, you must re-create the object first. This process can be done with different programming idioms. Choosing the wrong idiom can cause you problems. Consider the code idiom in Listing 3 for retrieving the referent object from a WeakReference
:
obj = wr.get(); if (obj == null) { wr = new WeakReference(recreateIt()); //1 obj = wr.get(); //2 } //code that works with obj |
After studying this code, consider the alternate code idiom in Listing 4 for retrieving the referent object from a WeakReference
:
obj = wr.get(); if (obj == null) { obj = recreateIt(); //1 wr = new WeakReference(obj); //2 } //code that works with obj |
Compare the two idioms to see if you can determine which one is guaranteed to work, and which one is not. The idiom outlined in Listing 3 is not guaranteed to work at all times, but Listing 4's idiom is. The reason the idiom in Listing 3 is deficient is because obj
is not guaranteed to be non-null after the body of the if
block completes. Consider what happens if the garbage collector runs after line //1 of Listing 3 but before line //2 executes. The recreateIt()
method re-creates the object, but it is referenced by a WeakReference
, not a strong reference. Therefore, if the collector runs before line //2 attaches a strong reference to the re-created object, the object is lost and wr.get()
returns null
.
Listing 4 does not have this problem because line //1 re-creates the object and assigns a strong reference to it. Therefore, if the garbage collector runs after this line, but before line //2, the object will not be reclaimed. Then, the WeakReference
to obj
is created at line //2. After working with obj
after this if
block, you should set obj
to null
to enable the garbage collector to reclaim this object to take full advantage of weak references. Listing 5 shows a complete program demonstrating the idiom differences just described. (To run this program, a "temp.fil" file must exist in the directory from which the program runs.)
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()); } } |
The Reference classes can be useful if used for the right situations. However, their usefulness is tempered by the fact that they rely on the sometimes unpredictable behavior of the garbage collector. Their effective use is also dependent on applying the correct programming idioms; it's critical that you understand how these classes are implemented and how to program to them.
<!-- CMA ID: 10717 --><!-- Site ID: 1 --><!--XSLT stylesheet used to transform this file: dw-document-html-6.0.xsl-->
- Sam Borman wrote an interesting series on the IBM Garbage Collector. Part 1 examines object allocation; Part 2 details garbage collection; and Part 3 explains how to interpret
verbosegc
and how some of the command-line parameters work.
- Jeff Friesen demonstrates how to use the Reference Object API to manage image caches, obtain notification when significant objects are no longer strongly reachable, and perform post-finalization cleanup in this article from JavaWorld (January 2002).
- Find hundreds of Java programming resources on the developerWorks Java technology zone.
This article originates from http://www.ibm.com/developerworks/library/j-refs/
发表评论
-
Zz The java.lang.LinkageError: loader constraint violation" demystified
2014-05-13 19:24 1508http://frankkieviet.blogspot.c ... -
zz Java NIO 系列教程
2014-05-09 22:38 1159http://www.iteye.com/magazines ... -
Zz Java NIO Tutorial
2014-05-09 22:34 1774http://tutorials.jenkov.com/ja ... -
Zz Spring IOC 好处和劣势
2014-03-28 18:06 1069IoC是什么? Inversion of Contro ... -
Zz ConcurrentHashMap源码解析
2014-03-16 17:29 664ConcurrentHashMap是Java 5中支持高并发 ... -
Zz Java多线程之ConcurrentHashMap深入分析
2014-03-16 14:50 1179一、Map体系 Hashtable是JDK ... -
Zz ConcurrentHashMap原理分析
2014-03-16 14:03 1125集合是编程中最常用的数据结构。而谈到并发,几乎总是离不开集合 ... -
Zz Java并发编程之ConcurrentHashMap
2014-03-16 13:40 2064ConcurrentHashMap Concurrent ... -
关于ConcurrentHashMap 中位移的问题
2014-03-16 14:33 1260拜读了GoldenDoc的大作:《Java并发编程之Con ... -
ConcurrentHashMap 详解
2014-03-15 21:19 01. ConcurrentHashMap 可以做到读取数 ... -
Why java Arrays use two different sort algorithms for different types?
2014-02-25 22:09 1295Java 7 uses Dual-Pivot Quicks ... -
深入探讨 java.lang.ref 包
2014-02-25 19:58 1089回顾了一下三年多前写的文章https://www.i ... -
Zz Java 中使用内存映射文件需要考虑的 10 个问题
2014-02-09 17:18 942java中的内存映射IO和内存映射文件是什么? 内存 ... -
Zz 10 Things to Know about Memory Mapped File in Java
2014-02-09 17:16 626What is Memory Mapped File ... -
Zz Direct vs non-direct ByteBuffer
2014-02-08 12:46 846先解释一下两者的区 ... -
Zz direct buffer VS non-direct buffer
2014-02-08 10:55 864在java NIO中,有两种不同的buffer:direct ... -
Java Generics 小结
2013-03-07 14:12 01. 泛型类型或泛型类 ... -
关于 Java正则表达式中的Possessive数量修饰词的理解
2013-02-26 21:14 1283正则表达式对于数量限定符如 ?, + , *, {n, m ... -
Run Application in debug mode
2013-01-23 13:59 1307Q: I use the Eclipse IDE to de ... -
一个 Dynamic Proxy 的例子
2012-11-22 11:18 1231最近翻出了两年前老吴让我写的一个MockFacotry , ...
相关推荐
types to Java classes by using either standard JDBC or Oracle extensions. Chapter 9, "Working with Oracle Object References" This chapter describes the Oracle extensions to standard JDBC that let you ...
Guidelines for Avoiding Race Conditions . . . . . . . . . . 183 Semaphores . . . . . . . 184 Portability Issues 186 Events from Overwritten Scheduled Values . . . . . . . . 186 Disabled Scheduled ...
Comparing Reference Types for Equality 142 The ReferenceEquals() Method 142 The virtual Equals() Method 143 The static Equals() Method 143 Comparison Operator (==) 143 Comparing Value Types for ...
- **Manual Reference Counting (MRC)**: In MRC, developers manually manage the memory lifecycle of objects using `retain` and `release` calls. - **Automatic Reference Counting (ARC)**: With ARC, the ...
Based on the provided information from the book "C# 3.0 With the .NET Framework 3.5 Unleashed," we can extract several key points and concepts that are essential for understanding the fundamentals of ...
The LML specification’s purpose is to provide a reference for users of the language to understand its goals, concepts and structure and to provide vendors a reference for implementation of the ...
Alongside this, language frameworks and the associated system classes are also described. ABAP - Overview An introduction to ABAP and the most important umbrella topics. ABAP Dictionary A ...
- **Strings Using Reference Semantics:** Explains reference semantics for strings. - **Constructor Issues and Mysteries:** Addresses common issues and misconceptions. - **Polymorphism Using Function ...
Modular Programming Modules Public and Private The extern Storage Class Headers The Body of the Module A Program to Use Infinite Arrays The Makefile for Multiple Files Using the Infinite Array ...
- **Creating Python Extension Modules with Delphi Classes and Functions**: Developers can create Python extension modules using Delphi classes and functions, enabling the creation of custom Python ...
The Future for Python 2.x Changes to the Handling of Deprecation Warnings Python 3.1 Features PEP 372: Adding an Ordered Dictionary to collections PEP 378: Format Specifier for Thousands Separator...
Essential C# 5.0 is a well-organized, no-fluff guide to the latest versions of C# for programmers at all levels of C# experience. Fully updated to reflect new features and programming patterns ...
The core module contains fundamental classes and functions that form the basis of SymPy. These include basic expression types and evaluation mechanisms. ##### 5.2 Combinatorics Module The ...
Classes:** Use structs for POD (Plain Old Data) types and classes for more complex types with behavior. - **Structs vs. Pairs and Tuples:** Use structs for named fields and pairs/tuples for small ...
- **Benefits:** Using properties instead of public data members enhances encapsulation and allows for validation logic, lazy loading, and caching without changing the API. - **Implementation:** Define...
the two of you grow up has been so rewarding and enjoyable for me. am lucky to be able to partake in your lives. love and ap preciate you more than you could ever know Contents at a glance ...
11.5 Discussion of the Range of Peak Temperatures for Lead-Free Assembly / 11.15 11.6 Lead-Free Applications and Ipc-4101 Specification Sheets / 11.15 11.7 Additional Base material Options for Lead-...