`
san_yun
  • 浏览: 2663240 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

利用ReferenceQueue实现自动清理的cache

 
阅读更多
理解StrongReference,SoftReference, WeakReference的区别(http://san-yun.iteye.com/blog/1683558)文中解释了各种Reference。 Reference都有构造函数可以传入ReferenceQueue来监听GC对referent的处理,构造函数如下:
Reference(T referent, ReferenceQueue<? super T> queue) {
	this.referent = referent;
	this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
    }


下面是一段测试代码:
	public class A {

	}

		ReferenceQueue queue = new ReferenceQueue();
		WeakReference ref = new WeakReference(new A(), queue);
		Assert.assertNotNull(ref.get());

		Object obj = null;
		obj = queue.poll();
		Assert.assertNull(obj);

		System.gc();

		Assert.assertNull(ref.get());
		obj = queue.poll();
		Assert.assertNotNull(obj);


分析,在GC运行时,检测到new A()生成的对象只有一个WeakReference引用着,所以决定回收它,首先clear WeakReference的referent,然后referent的状态为finalizable,同时或者一段时间后把WeakReference放入监听的ReferenceQueue中。

注意有时候最后的Assert.assertNotNull(obj);有时会失败,因为还没有来的及把WeakReference放入监听的ReferenceQueue中。


下面是一个可自动回收的map实现:

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

public class WeakIdentityMap {

	private transient ReferenceQueue<Object> idKeys = new ReferenceQueue<Object>();

	private Map<WeakIdKey, Object> objHashcodeToPyId = new HashMap<WeakIdKey, Object>();

	@SuppressWarnings("element-type-mismatch")
	private void cleanup() {
		Object k;
		while ((k = idKeys.poll()) != null) {
			System.out.println("cleanup");
			objHashcodeToPyId.remove(k);
		}
	}

	private class WeakIdKey extends WeakReference<Object> {
		private final int hashcode;

		WeakIdKey(Object obj) {
			super(obj, idKeys);
			hashcode = System.identityHashCode(obj);
		}

		@Override
		public int hashCode() {
			return hashcode;
		}

		@Override
		public boolean equals(Object other) {
			Object obj = get();
			if (obj != null) {
				return obj == ((WeakIdKey) other).get();
			} else {
				return this == other;
			}
		}
	}

	// Used by test_jy_internals
	public int _internal_map_size() {
		return objHashcodeToPyId.size();
	}

	public void put(Object key, Object val) {
		cleanup();
		objHashcodeToPyId.put(new WeakIdKey(key), val);
	}

	public Object get(Object key) {
		cleanup();
		return objHashcodeToPyId.get(new WeakIdKey(key));
	}

	public void remove(Object key) {
		cleanup();
		objHashcodeToPyId.remove(new WeakIdKey(key));
	}

	public static void main(String[] args) throws InterruptedException {
		WeakIdentityMap map = new WeakIdentityMap();
		map.put("1", "a");
		map.put(new Object(), "b");
		map.put(new Object(), "2");
		System.gc();
		Thread.sleep(1000);
		map.put("1", "a");
		
	}
}



参考:http://zhang-xzhi-xjtu.iteye.com/blog/413159
分享到:
评论

相关推荐

    详解Java对象的强、软、弱和虚引用+ReferenceQueue

    WeakHashMap是弱引用map,就是Key键是一个弱引用的键,如果Key键被回收,则在get该map中值后,会自动remove掉value。如果Key键始终被强引用,则是无法被回收的;注意Value是被强引用的,所以不要让Value间接的引用了...

    Java编程WeakHashMap实例解析

    WeakHashMap的实现原理是使用WeakReference来保存键和值,WeakReference是一个弱引用的实现,它可以在垃圾回收器清理对象时自动清理对象的引用。在WeakHashMap中,每个键和值都是WeakReference对象,这样可以使得...

    线程池调用队列

    在Java中,`java.util.concurrent`包提供了线程池的相关实现,如`ThreadPoolExecutor`。`ThreadPoolExecutor`类的构造函数接受多个参数,其中包括核心线程数、最大线程数、线程空闲时间、线程存活时间单位以及工作...

    程序避免被GC 回收 --------引用

    在Java中,垃圾收集(Garbage Collection, GC)机制自动管理内存资源,有效地解决了手动管理内存时可能遇到的问题,如内存泄漏等。然而,在某些情况下,我们希望某些对象能尽可能长时间地存活在内存中,而不被GC回收...

    Java 引用1

    例如,如果你希望在内存不足时自动清理缓存,可以使用软引用;如果希望对象在任何情况下都能被回收,可以选择弱引用;而虚引用则常用于在对象被回收前执行某些清理工作。理解并正确使用这些引用类型,对于编写高效、...

    Java中弱引用软引用虚引用及强引用的区别Java开发Ja

    例如,在缓存系统中,使用软引用可以实现自动释放资源的缓存策略,当内存紧张时,不再使用的缓存项会被自动回收。而弱引用则常用于避免内存泄漏,确保对象在不再被程序其他部分引用时能被及时清理。 在Java开发中,...

    Java对象的引用.pdf

    这在实现一些缓存机制时非常有用,例如,在内存充足时缓存对象,在内存紧张时自动释放这些对象。 接下来是软引用(SoftReference)。软引用是一种比弱引用更强的引用,只有在JVM认为内存不足的情况下,才会回收被软...

    Java基础总结下1

    Reference和ReferenceQueue可以实现对象的软引用、弱引用和虚引用,用于内存管理。 总的来说,Java的基础知识体系广泛且深入,涵盖了从基本语法、输入输出、集合框架到高级特性的方方面面,对于开发者来说,理解和...

    Java引用类型1

    引用队列(ReferenceQueue)是与引用类型配合使用的工具,当弱引用或虚引用的对象被垃圾收集后,它们会自动加入到引用队列,方便程序进行后续的清理工作。 总结来说,Java的引用类型提供了一种控制对象生命周期的...

    详解java中finalize的实现与相应的执行过程

    Java中的`finalize`方法是Object类的一个特殊方法,它的主要作用是在对象被垃圾收集器回收前执行清理工作。本文将详细解析`finalize`方法的实现和执行过程。 首先,了解`finalize`方法的用途:当一个对象不再被任何...

    Android高级进阶知识点

    软引用(SoftReference)用于缓存临时数据,其引用的对象被回收后,SoftReference对象本身不会自动清理,需要一个清除机制来避免内存泄露。当软引用对象被垃圾回收器回收后,SoftReference对象会被放入到...

    Java 7之基础 - 强引用、弱引用、软引用、虚引用1

    Java的垃圾收集机制自动处理不再使用的对象,以便有效地利用系统资源。然而,为了更好地控制内存,Java提供了不同类型的引用:强引用、弱引用、软引用和虚引用。这些引用类型允许程序员在特定场景下干预垃圾收集过程...

    Java Garbage Collection Study java 垃圾回收学习

    - **虚引用(Phantom References)**:几乎任何时候都可以被回收,通常与`ReferenceQueue`结合使用,管理与对象关联的本地资源清理,而不依赖于`finalize()`方法。 了解这些引用类型的行为对于有效地管理Java程序的...

    解析Android开发优化之:软引用与弱引用的应用

    通过创建一个`SoftReference&lt;Bitmap&gt;`实例并将Bitmap对象保存在`HashMap`中,我们可以在需要时快速访问图片,而当内存紧张时,软引用的对象会被自动清理,防止内存溢出。 软引用可以与`ReferenceQueue`一起使用,当...

    强,软,弱,虚1

    虚引用必须与引用队列(ReferenceQueue)配合使用,当对象被回收时,虚引用会被放入队列,这样开发者可以通过队列知道何时可以安全地进行资源释放。 总结来说,这四种引用类型在内存管理中各有其用处。强引用保证...

    详解java中Reference的实现与相应的执行过程

    在Java中,`Reference`类是一个特殊...在实际编程中,选择合适的引用类型取决于应用场景,例如,使用 `WeakHashMap` 可以在对象不再被强引用时自动移除,而 `PhantomReference` 则用于在对象被彻底回收后执行清理工作。

    Java中的强软弱虚引用

    虚引用主要用于实现对象的“finalize”机制,即在对象被垃圾回收前执行一些清理工作,如关闭文件等。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象之前,把这个虚引用加入到与之关联的队列...

    Java中管理资源的引用队列相关原理解析

    在实际应用中,我们可以利用引用队列来实现资源的自动管理。例如,当一个对象不再需要某个资源时,可以使用虚引用(`PhantomReference`)来追踪这个对象。由于虚引用在对象被终结(finalization)后才加入队列,因此...

    Java中弱引用和软引用的区别以及虚引用和强引用介绍

    - **资源清理**:虚引用配合引用队列可以实现对象回收后的资源清理,例如关闭文件流或其他资源。 理解并正确使用这些引用类型是优化Java应用程序性能和内存管理的关键。在设计内存敏感的系统时,合理选择引用类型能...

    java 引用相关文档

    只有在内存不足时,软引用对象才会被清理,以防止`OutOfMemoryError`的发生。 - 示例:`SoftReference&lt;String&gt; softRef = new SoftReference(new String("Hello"));` 3. **弱引用(Weak Reference)** - 弱引用比...

Global site tag (gtag.js) - Google Analytics