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数组,
所以偶那些对象不能被垃圾回收器回收。
发表评论
-
仿真[汽车制造]
2012-02-13 01:26 685class Car{ private final i ... -
线程例子[Condition, SignlAll, await]
2012-02-09 22:05 1031package concurrency.waxomati ... -
生产者消费者[简单示例]
2012-02-09 21:38 659class Meal{ private final ... -
泛型[创建类型实例]
2012-02-06 01:01 738public Class Erased<T> ... -
多路分发3
2012-02-05 23:16 828使用常量相关的方法 常量相关的方法允许我们为每个 ... -
多路分发2[使用enum分发]
2012-02-05 18:09 1903直接将RoShamBo1.java翻译为基于enum的版 ... -
多路分发
2012-02-05 02:06 1384多路分发 Number.plus(Number) ... -
使用Enum的自动贩卖机
2012-02-04 13:52 923public enum Input { NICKEL ... -
使用enum的责任链
2012-02-04 12:39 1179package enumerated; impor ... -
枚举类Enum,EnumSet,EnumMap
2012-02-04 02:00 1422EnumSet与HashSet相比,非常快。 p ... -
枚举类enum
2012-02-03 15:00 904一般来说,我们希望每个美剧实例能够返回对自身的描述, ... -
类的简化历[从内部类到匿名内部类]
2012-02-02 12:41 634Version1: public class DirL ... -
Collections快速报错 fial-fast
2012-02-02 00:46 787{ public static void main( ... -
散列HashCode
2012-02-01 14:04 704散列的价值在于速度: 散列使得查询快速,由于瓶颈位于键 ... -
使用散列数据结构注意点
2012-02-01 01:32 591Goundhog自动继承基类Object,所以这里使用 ... -
Set注意点
2012-02-01 01:31 308如果我们尝试着将没有恰当支持不许的操作的类型用于需要这些 ... -
享元Map
2012-01-30 00:28 381这里之所以叫享元,注意static关键字。 定制了Entry ... -
深入容器Map
2012-01-19 15:12 398Map生成器 对Map的使用相同的方式,需要一 ... -
深入容器List
2012-01-19 14:40 343一种Generator解决方案: 所有Collect ... -
泛型数组
2012-01-19 00:57 638不能创建泛型数组,但能通过转型来赋予 public cl ...
相关推荐
12. WeakHashMap:键使用弱引用的Map,当键不再被引用时,条目会自动从Map中移除。 13. Timer和TimerTask:定时任务调度,可以安排一次或周期性的任务执行。 14. Bitset:位集,用于高效存储和操作位标志。 15. ...
在`java.lang`和`java.util.concurrent`包中,Java 6提供了丰富的多线程支持。Thread类代表程序中的执行线程,Runnable接口定义了线程执行的代码。此外,ExecutorService和ThreadPoolExecutor提供了线程池管理,避免...
Java的基础语法包括变量(Variable)、数据类型(如基本类型和引用类型)、运算符、控制结构等。变量用于存储数据,数据类型则分为基本类型(如int、float、boolean等)和引用类型(如类、接口和数组)。运算符包括...
在变量声明和数据类型上,Java有基本类型(如int、float、boolean等)和引用类型(如类、接口、数组)。变量可以被声明为static或final,其中static关键字用于定义静态成员,而final则表示不可改变的常量或类。 ...
Java.IO Java.lang Java.math Java.net Java 基础核心总结 V2.0 IO 传统的 BIO BIO NIO 和 AIO 的区别什么是流 流的分类 节点流和处理流 Java IO 的核心类 File Java IO 流对象 字节流对象InputStream ...
WeakHashMap是Java中的一种哈希映射表,它的键是弱引用的,意味着当 WeakHashMap 的键对象只有 WeakHashMap 自己持有时,垃圾回收器可以将其回收。WeakHashMap 的使用方法主要体现在以下几个方面: 1. WeakHashMap...
在Java中,弱引用由`java.lang.ref.WeakReference<T>`类表示。官方文档指出,弱引用的对象不会阻止它所指向的对象被垃圾回收器回收。即使有弱引用指向一个对象,只要没有其他强引用存在,垃圾收集器就会回收这个对象...
弱引用是Java中的一种引用类型,位于Java的java.lang.ref包下,主要由WeakReference类表示。与强引用(Strong Reference)不同,弱引用对象的存在不会阻止垃圾回收器对它所指向的对象进行回收。即使有弱引用指向一个...
WeakHashMap是Java中的一种特殊的哈希表实现,它使用弱引用(Weak Reference)来保存键对象。当键对象没有被其他强引用引用时,在垃圾回收时会自动从WeakHashMap中移除对应的键值对。
Java 1.6后提供了`WeakHashMap`,可以用于存储弱引用的观察者。 - **多参数通知**:默认的`update`方法只传递了一个`Object`参数,可能无法满足复杂场景的需求。可以通过自定义参数类型或使用`java.util.EventObject...
Java集合框架包括接口(如List、Set、Map)和实现这些接口的类,如ArrayList、Vector、LinkedList、Stack、HashSet、TreeSet、LinkedHashSet、PriorityQueue、HashMap、TreeMap、LinkedHashMap、Hashtable、...
### Java避免内存泄露的关键知识点 #### 一、内存泄露的概念及原因 内存泄露是指程序在申请内存后未能释放,导致这部分内存无法再次被...正确地管理资源和引用,不仅可以提升程序的健壮性,还能提高系统的整体性能。
WeakHashMap是Java编程中的一种特殊的HashMap实现,它使用弱引用来保存键和值,这样可以使得垃圾回收器自动清理键和值。在WeakHashMap中,键和值都是弱引用的,这样可以避免内存泄露的问题。 WeakHashMap的实现...
这些智能引用类型配合相应的容器类,如`java.lang.ref.ReferenceQueue`和`java.util.WeakHashMap`,可以在特定场景下实现高效和灵活的对象管理。例如,`WeakHashMap`中的键使用弱引用,当键的对象被垃圾收集时,键值...
Java 支持多种数据类型,包括基本数据类型(如 `int`, `double`, `char` 等)和引用数据类型(如类、数组等)。 - **基本数据类型**:例如 `int` 用于整数,`double` 用于浮点数。 - **引用数据类型**:指向对象的...
反射是Java语言的一个重要特性,它基于Java.lang.Class类和java.lang.reflect包中的API。通过Class对象,我们可以获取到类的信息(如类名、方法、属性等),并能在运行时创建对象、调用方法、访问字段。 2. **反射...
`WeakHashMap`是一种特殊的Map,它的键使用弱引用,当键不再被引用时,键值对会自动从Map中移除。 遍历集合时,`iterator()`方法是核心,它返回一个迭代器,通过`hasNext()`和`next()`方法可以依次访问集合中的元素...