`
racingbird
  • 浏览: 23371 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

持有引用java.lang.ref 和 WeakHashMap

 
阅读更多

Thinking in java P554

 

 

持有引用

如果想继续持有对某个对象的引用,希望以后能够反问到该对象,

但是也希望能够允许垃圾回收器是否它,这是就应该使用Reference

对象。这样,可以继续使用改对象,而再内存消耗完时允许是否它。

 

以Reference对象作为你和普通引用的媒介,另外,一定不能有

普通的引用指向那个兑现g.zheyang就能达到上述目的。

(普通的引用指没有经Reference对象包装过的引用)。

如果垃圾回收器发现某个兑现沟通过普通引用是可获得的,该

对象就不会被释放。

 

SoftReference, WeakReference 和 PhantomReference由强到若,

对应不同级别的"可获得性".Softreference用以是想内存

敏感的高速缓存。Weak reference是为实现个"规范映射"

而设计的,它部妨碍垃圾回收器回收映射的键或值。

规范映射中对象的实力可以在程序的多处被同时使用,

以节省存储空间。Phantomreference用以调度回收前

的清理工作,比Java终止机制更灵活。

 

 

class VeryBig {
	private static final int SIZE = 10000;
	private long[] la = new long[SIZE];
	private String ident;
	public VeryBig(String id){
		ident = id;
	}
	@Override
	public String toString() {
		return ident;
	}
	
	@Override
	protected void finalize() throws Throwable {
		System.out.println("Finalizing "+ident);
	}
}

public class References{
	private static ReferenceQueue<VeryBig> rq = 
		new ReferenceQueue<VeryBig>();

	public static void checkQueue(){
		Reference<? extends VeryBig> inq = rq.poll();
		if(inq != null)
			System.out.println("In Queue: "+inq.get());
	}
	
	public static void main(String[] args) {
		int size = 10;
		
		if(args.length > 0)
			size = new Integer(args[0]);
		LinkedList<SoftReference<VeryBig>> sa =
			new LinkedList<SoftReference<VeryBig>>();
		for(int i=0; i<size; i++){
			sa.add(new SoftReference<VeryBig>(
					new VeryBig("Soft "+ i), rq)
				);
			System.out.println("Just created: "+sa.getLast());
			checkQueue();
		}
		
		LinkedList<WeakReference<VeryBig>> wa =
			new LinkedList<WeakReference<VeryBig>>();
		for(int i=0; i<size; i++){
			wa.add(new WeakReference<VeryBig>(
					new VeryBig("Weak "+ i), rq)
			);
			System.out.println("Just created: "+wa.getLast());
			checkQueue();
		}
		
		SoftReference<VeryBig> s =
			new SoftReference<VeryBig>(new VeryBig("Soft"));
		
		WeakReference<VeryBig> w =
			new WeakReference<VeryBig>(new VeryBig("Weak"));
		
		System.gc();
		
		LinkedList<PhantomReference<VeryBig>> pa =
			new LinkedList<PhantomReference<VeryBig>>();
		for(int i=0; i<size; i++){
			pa.add(new PhantomReference<VeryBig>(
					new VeryBig("Phantom "+ i), rq)
			);
			System.out.println("Just created: "+pa.getLast());
			checkQueue();
		}
	}
}

 

结果

 

Just created: java.lang.ref.WeakReference@1d5550d

Just created: java.lang.ref.WeakReference@c2ea3f

Just created: java.lang.ref.WeakReference@a0dcd9

Just created: java.lang.ref.WeakReference@1034bb5

Just created: java.lang.ref.WeakReference@f9f9d8

Finalizing Weak 0

Finalizing Weak

Finalizing Weak 8

Finalizing Weak 7

Finalizing Weak 6

Finalizing Weak 5

Finalizing Weak 4

Finalizing Weak 3

Finalizing Weak 2

Finalizing Weak 1

Finalizing Weak 9

Just created: java.lang.ref.PhantomReference@112f614

In Queue: null

Just created: java.lang.ref.PhantomReference@1d9dc39

In Queue: null

Just created: java.lang.ref.PhantomReference@93dcd

In Queue: null

Just created: java.lang.ref.PhantomReference@b89838

In Queue: null

Just created: java.lang.ref.PhantomReference@111a3ac

In Queue: null

Just created: java.lang.ref.PhantomReference@dd20f6

In Queue: null

Just created: java.lang.ref.PhantomReference@723d7c

In Queue: null

Just created: java.lang.ref.PhantomReference@1d1acd3

In Queue: null

Just created: java.lang.ref.PhantomReference@8814e9

In Queue: null

Just created: java.lang.ref.PhantomReference@1503a3

In Queue: null


 

 

 

尽管还要通过Reference对象访问那些对象(使用get()取得实际的对象引用),

但是还是被垃圾回收器回收了。

可以看到,REferenceQueue总是生成一个包含null对象的Reference.

 

 

 

 

容器中WeakHashMap,用来保存WeakReference。每个值只保存一份实例

以节省存储空间,查值,则在映射中查询现有对象,然后使用它。

映射可将值作为其初始化一部分,不过通常是在需要的时候才生成值。

 

对于向WeakHashMap添加键和值的操作,没有什么特殊要求,映射会

自动使用WeakReference包装他们。允许清理元素的触发条件是,

不需要这个键。

 

class Element{
	private String ident;
	public Element(String id){
		ident = id;
	}
	public String toString(){
		return ident;
	}
	public int hashCode(){
		return ident.hashCode();
	}
	public boolean equals(Object r){
		return r instanceof Element && 
			ident.equals(((Element)r).ident);
	}
	protected void finalize(){
		System.out.println("Finalizing "+
				getClass().getSimpleName()+" "+ident);
	}
}

class Key extends Element{
	public Key(String id){
		super(id);
	}
}

class Value extends Element{
	public Value(String id){
		super(id);
	}
}

public class CanonicalMapping {
	public static void main(String[] args) {
		int size = 1000;
		if(args.length > 0)
			size = new Integer(args[0]);
		Key[] keys = new Key[size];
	
		WeakHashMap<Key, Value> map =
			new WeakHashMap<Key, Value>();
		for(int i=0; i<size; i++){
			Key k = new Key(Integer.toString(i));
			Value v = new Value(Integer.toString(i));
			if(i%3==0)
				keys[i] = k;
			map.put(k, v);
		}
		System.gc();
	}
}

 

结果:

zing Key 209

Finalizing Key 208

Finalizing Key 206

Finalizing Key 205

Finalizing Key 203

Finalizing Key 202

Finalizing Key 200

Finalizing Key 199

Finalizing Key 197

Finalizing Key 196

Finalizing Key 194

Finalizing Key 193

Finalizing Key 191

Finalizing Key 190

Finalizing Key 188

...

可以看到垃圾回收期每隔三个键就跳过一个,因为指向那个键的普通引用被存如了Keys数组,

所以偶那些对象不能被垃圾回收器回收。

分享到:
评论

相关推荐

    java.util包总结

    12. WeakHashMap:键使用弱引用的Map,当键不再被引用时,条目会自动从Map中移除。 13. Timer和TimerTask:定时任务调度,可以安排一次或周期性的任务执行。 14. Bitset:位集,用于高效存储和操作位标志。 15. ...

    JAVASE6.0_Api_en\docs\api

    在`java.lang`和`java.util.concurrent`包中,Java 6提供了丰富的多线程支持。Thread类代表程序中的执行线程,Runnable接口定义了线程执行的代码。此外,ExecutorService和ThreadPoolExecutor提供了线程池管理,避免...

    Java基础核心总结.pdf

    在变量声明和数据类型上,Java有基本类型(如int、float、boolean等)和引用类型(如类、接口、数组)。变量可以被声明为static或final,其中static关键字用于定义静态成员,而final则表示不可改变的常量或类。 ...

    Java 基础核心总结 +经典算法大全.rar

    Java.IO Java.lang Java.math Java.net Java 基础核心总结 V2.0 IO 传统的 BIO BIO NIO 和 AIO 的区别什么是流 流的分类 节点流和处理流 Java IO 的核心类 File Java IO 流对象 字节流对象InputStream ...

    WeakHashMap的使用方法详解

    WeakHashMap是Java中的一种哈希映射表,它的键是弱引用的,意味着当 WeakHashMap 的键对象只有 WeakHashMap 自己持有时,垃圾回收器可以将其回收。WeakHashMap 的使用方法主要体现在以下几个方面: 1. WeakHashMap...

    10分钟带你理解Java中的弱引用

    在Java中,弱引用由`java.lang.ref.WeakReference&lt;T&gt;`类表示。官方文档指出,弱引用的对象不会阻止它所指向的对象被垃圾回收器回收。即使有弱引用指向一个对象,只要没有其他强引用存在,垃圾收集器就会回收这个对象...

    java集合-WeakHashMap的使用

    WeakHashMap是Java中的一种特殊的哈希表实现,它使用弱引用(Weak Reference)来保存键对象。当键对象没有被其他强引用引用时,在垃圾回收时会自动从WeakHashMap中移除对应的键值对。

    Thinking in Java 4th Edition

    Java SE5 and SE6 .................. 2 Java SE6 ......................................... 2 The 4th edition........................ 2 Changes .......................................... 3 Note on the ...

    Java内置观察者模式

    Java 1.6后提供了`WeakHashMap`,可以用于存储弱引用的观察者。 - **多参数通知**:默认的`update`方法只传递了一个`Object`参数,可能无法满足复杂场景的需求。可以通过自定义参数类型或使用`java.util.EventObject...

    Java 软件开发复习提纲.pdf

    Java集合框架包括接口(如List、Set、Map)和实现这些接口的类,如ArrayList、Vector、LinkedList、Stack、HashSet、TreeSet、LinkedHashSet、PriorityQueue、HashMap、TreeMap、LinkedHashMap、Hashtable、...

    Java编程WeakHashMap实例解析

    WeakHashMap是Java编程中的一种特殊的HashMap实现,它使用弱引用来保存键和值,这样可以使得垃圾回收器自动清理键和值。在WeakHashMap中,键和值都是弱引用的,这样可以避免内存泄露的问题。 WeakHashMap的实现...

    smartref:Java 1.5+ 的简单引用类型和容器

    这些智能引用类型配合相应的容器类,如`java.lang.ref.ReferenceQueue`和`java.util.WeakHashMap`,可以在特定场景下实现高效和灵活的对象管理。例如,`WeakHashMap`中的键使用弱引用,当键的对象被垃圾收集时,键值...

    JAVA-提高反射效率

    反射是Java语言的一个重要特性,它基于Java.lang.Class类和java.lang.reflect包中的API。通过Class对象,我们可以获取到类的信息(如类名、方法、属性等),并能在运行时创建对象、调用方法、访问字段。 2. **反射...

    细说Java之util类.

    `WeakHashMap`是一种特殊的Map,它的键使用弱引用,当键不再被引用时,键值对会自动从Map中移除。 遍历集合时,`iterator()`方法是核心,它返回一个迭代器,通过`hasNext()`和`next()`方法可以依次访问集合中的元素...

    Java引用类型1

    Java提供了四种不同级别的引用类型:强引用、软引用、弱引用和虚引用(幻象引用),每种引用类型在内存管理中有不同的作用。 1. **强引用(Strong Reference)** - 强引用是最常见的引用类型,即通常的变量赋值。...

    Java 基础核心总结-.pdf

    Java 提供了丰富的集合类,如ArrayList、Vector、LinkedList、Stack、HashSet、TreeSet、LinkedHashSet、PriorityQueue、HashMap、TreeMap、LinkedHashMap、Hashtable、IdentityHashMap、WeakHashMap等。Collections...

    Java弱引用与WeakHashMap

    在《Effective Java 2nd Edition》中,第6条“消除过期的对象引用”提到,虽然Java有垃圾回收机制,但是只要是自己管理的内存,应该警惕内存泄露的问题,例如的对象池、缓存中的过期对象都有可能引发内存泄露的问题...

    疯狂java讲义代码.rar

    - **变量与数据类型**:包括基本数据类型(如int、char、boolean等)和引用数据类型(如类、接口和数组)。 - **运算符与表达式**:学习各种算术、关系、逻辑、位和赋值运算符,以及它们在表达式中的应用。 - **...

    Java基础总结(程序员cxuan编写)1

    10. **包与命名空间**:Java通过包(package)进行模块化管理,避免了命名冲突,如java.io和java.lang是常见的标准库包。 11. **多线程**:Java内置了对多线程的支持,可以通过实现Runnable接口或继承Thread类创建...

Global site tag (gtag.js) - Google Analytics