`
风过无声
  • 浏览: 93075 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JAVA中的4种Reference

 
阅读更多

在jdk 1.2及其以后,引入了强引用、软引用、弱引用、虚引用这四个概念。

1.强引用

StrongReference是Java的默认引用实现,它会尽可能长时间的存活于JVM内,当没有任何对象指向它时GC执行后将会被回收。

2.软引用

SoftReference在JVM报告内存不足的时候才会被GC回收,否则不会回收,正是由于这种特性软引用在内存敏感的caching和pooling中用处广泛。

此类的直接实例可用于实现简单缓存;该类或其派生的子类还可用于更大型的数据结构,以实现更复杂的缓存。只要软引用的指示对象是强可到达对象,即正在实际使用的对象,就不会清除软引用。例如,通过保持最近使用的项的强指示对象,并由垃圾回收器决定是否放弃剩余的项,复杂的缓存可以防止放弃最近使用的项。  

 

@Test
public void softReference() {
	Object referent = new Object();   
       
    /**  
     * 创建 SoftReference   
     */  
	SoftReference<Object> softReference = new SoftReference<Object>(referent);   
       
    assertSame(referent, softReference.get());   
    
    referent = null;
    System.gc();   
       
    /**  
     * soft references 只有在 jvm OutOfMemory 之前才会被回收, 所以它非常适合缓存应用
     */  
    assertNotNull(softReference.get()); 
}

 

3.弱引用

在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

@Test
public void weakReference() {
	Object referent = new Object();   
       
    /**  
     * 创建 WeakReference   
     */  
	WeakReference<Object> weakReference = new WeakReference<Object>(referent);   
       
    assertSame(referent, weakReference.get());   
    
    referent = null;
    System.gc();   
       
    /**  
     * 一旦没有指向 referent 的强引用, weak reference 在 GC 后会被自动回收
     */  
    assertNull(weakReference.get()); 
}

 

4.虚引用

虚引用对象,在回收器确定其指示对象可另外回收之后,被加入队列。虚引用最常见的用法是以某种可能比使用 Java 终结机制更灵活的方式来指派 pre-mortem 清除动作。 

如果垃圾回收器确定在某一特定时间点上虚引用的指示对象是虚可到达对象,那么在那时或者在以后的某一时间,它会将该引用加入队列。 

为了确保可回收的对象仍然保持原状,虚引用的指示对象不能被获取:虚引用的 get 方法总是返回 null。 

与软引用和弱引用不同,虚引用在加入队列时并没有通过垃圾回收器自动清除。通过虚引用可到达的对象将仍然保持原状,直到所有这类引用都被清除,或者它们都变得不可到达。

PhantomReferences对象是在对象从内存中清除出去的时候才入队的。也就是说当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

好处:

1)它可以让我们准确地知道对象何时被从内存中删除, 这个特性可以被用于一些特殊的需求中(例如 Distributed GC,  XWork 和 google-guice 中也使用 PhantomReference 做了一些清理性工作)。

2)它可以避免 finalization 带来的一些根本性问题, 上文提到 PhantomReference 的唯一作用就是跟踪 referent 何时被 enqueue 到 ReferenceQueue 中,  但是 WeakReference 也有对应的功能, 两者的区别到底在哪呢 ?

这就要说到 Object 的 finalize 方法, 此方法将在 gc 执行前被调用, 如果某个对象重载了 finalize 方法并故意在方法内创建本身的强引用,  这将导致这一轮的 GC 无法回收这个对象并有可能引起任意次 GC, 最后的结果就是明明 JVM 内有很多 Garbage 却 OutOfMemory, 使用 PhantomReference 就可以避免这个问题, 因为 PhantomReference 是在 finalize 方法执行后回收的,也就意味着此时已经不可能拿到原来的引用,  也就不会出现上述问题,  当然这是一个很极端的例子, 一般不会出现。

static class Entity {

	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		System.out.println("finalize...");
	}
	
}

@Test
public void phantomReferenceEntity() {
	Entity referent = new Entity();  
	
	/**  
     * 创建 PhantomReference   
     */  
	ReferenceQueue<Entity> queue = new ReferenceQueue<Entity>();
	PhantomReference<Entity> phantomReference = new PhantomReference<Entity>(referent, queue);
	
	referent = null;
    System.gc();  
    
    assertNull(queue.poll());
    
    try {
		Thread.currentThread().sleep(3000);
		System.gc();
		
		System.out.println("after finalize...");
		assertNotNull(queue.poll());
	} catch (InterruptedException e) {
		e.printStackTrace();
	}

}

5.可到达性

从最强到最弱,不同的可到达性级别反映了对象的生命周期。在操作上,可将它们定义如下: 

1)如果某一线程可以不必遍历所有引用对象而直接到达一个对象,则该对象是强可到达对象。新创建的对象对于创建它的线程而言是强可到达对象。 

2)如果一个对象不是强可到达对象,但通过遍历某一软引用可以到达它,则该对象是软可到达对象。 

3)如果一个对象既不是强可到达对象,也不是软可到达对象,但通过遍历弱引用可以到达它,则该对象是弱可到达对象。当清除对某一弱可到达对象的弱引用时,便可以终止此对象了。 

4)如果一个对象既不是强可到达对象,也不是软可到达对象或弱可到达对象,它已经终止,并且某个虚引用在引用它,则该对象是虚可到达对象。 

5)最后,当不能以上述任何方法到达某一对象时,该对象是不可到达对象,因此可以回收此对象。

6.参考资料

http://www.iteye.com/topic/401478

http://blog.sina.com.cn/s/blog_8417aea80100skwx.html

http://blog.sina.com.cn/s/blog_667ac0360102e9f3.html

分享到:
评论

相关推荐

    Java The Complete Reference, 11th Edition 9781260440232 c.pdf

    Java The Complete Reference, 11th Edition 9781260440232 c.pdf Java The Complete Reference, 11th Edition 9781260440232 c.pdf Java The Complete Reference, 11th Edition 9781260440232 c.pdf

    Java The Complete Reference 10th Edition

    Java The Complete Reference 10th Edition Java9 编程官方参考(第10版) 带书签 文字版

    Java功底之Reference

    在Java编程语言中,`Reference`类是一个非常特殊且重要的概念,它超出了常规的引用类型,如`Object`或数组引用。`Reference`类及其子类主要用于处理对象的软引用、弱引用和虚引用,这些引用类型在内存管理,特别是...

    Java The Complete Reference 9th

    在《Java The Complete Reference 9th》中,关于如何使用Java进行文件I/O操作、序列化对象以及使用Java NIO(新I/O)API进行高级I/O操作的内容,为读者提供了完整而深入的理解。 作为Java EE的重要组成部分,...

    Java The Complete Reference ,11th Edition.pdf

    Java: The Complete Reference, Eleventh Edition By 作者: Herbert Schildt ISBN-10 书号: 1260440230 ISBN-13 书号: 9781260440232 Edition 版本: 11 出版日期: 2018-12-12 pages 页数: (1955) The Definitive ...

    The Java Reference Library

    Java in a Nutshell Java Language Reference Java AWT Reference Java Fundamental Classes Reference Exploring Java Combined Index Combined Search Web Version Credits

    A Java Reference: Assorted Java Reference Material

    Your author likes to read reference manuals (believe it or not)—at least if they are reasonably complete—on the grounds that this is the most efficient way to absorb a language quickly.

    Neo4j Java Reference 3.0

    自定义过程是Neo4j的一种扩展方式,它允许开发者编写Java代码并部署到数据库中,在Cypher查询语言中直接调用。下面是一些关于自定义过程的重要概念: - **编写与部署**:自定义过程使用Java编写,并编译成jar文件。...

    neo4j-java-reference-3.3

    4. **在Java应用程序中嵌入Neo4j**:介绍了如何将Neo4j嵌入到自己的Java应用程序中,并给出了一些具体的示例代码和配置说明。 5. **遍历框架**:提供了Neo4j遍历框架的详细教程,帮助开发者了解如何利用框架进行...

    Java Reference Sheet

    Java reference sheet

    Java:The Complete Reference,J2SE 5 Edition

    中文译名是J2SE参考大全(第5版) 这份是自己制作的电子书,现在还没有制作完成,因为内容太多,关打字就打个半死.

    Java+The+Complete+Reference+9+src

    在《Java The Complete Reference》这本书中,作者详细介绍了Java的核心特性,包括: 1. **基础语法**:如数据类型、变量、运算符、控制结构(条件语句、循环语句)以及方法的定义与调用。 2. **面向对象编程**:...

    Java AWT Reference

    开发者不仅要学习Java 1.1中的新特性,还要判断何时可以在代码中安全地应用这些特性,关键在于主流浏览器(如Netscape Navigator)何时能支持Java 1.1。虽然有传言称支持即将到来,但考虑到软件维护的复杂性以及...

    java的primitive和reference类.docx

    Java 作为一种面向对象的语言,数据类型可以分为两类:Primitive 类型和 Reference 类型。Primitive 类型包括数字和布尔类型,不被看做对象,而是被称为基本类型。Reference 类型包括对象、接口和数组类型的数据的...

    Java - The complete reference - Eleventh edition

    ### Java - The Complete Reference - Eleventh Edition #### 1. The History and Evolution of Java - **起源与发展**:Java 语言由 Sun Microsystems 的 James Gosling 领导的一个团队于 1995 年发布。最初是为...

    Java:The Complete Reference,J2SE 5 Edition

    中文译名是J2SE参考大全(第5版) 这份是自己制作的电子书,现在还没有制作完成,因为内容太多,关打字就打个半死.

    spring-javaconfig-reference

    Spring JavaConfig为Spring框架提供了一种全新的配置方式,它利用Java语言的强大功能来替代传统的XML配置文件。这不仅提高了代码的可读性和可维护性,还充分利用了Java的静态类型检查等优势,使得开发者能够更加专注...

    Java The Complete Reference 8ED. DOC

    通过学习《Java The Complete Reference》第八版,开发者不仅可以掌握Java 7的核心知识,还能了解到如何在实际项目中应用这些知识,为成为熟练的Java开发者奠定了坚实的基础。这本书是Java程序员必备的参考书之一,...

Global site tag (gtag.js) - Google Analytics