java基础之java.lang.ref.Reference
2014-06-05 00:00
393 查看
Reference
java.lang.ref类库主要作用在于当内存不足时,能够提醒gc,将一些使用ref定义的变量释放掉以缓解内存不足的压力。java.lang.ref.Reference有三种不同的子类,SoftReference,WeakReference以及PhantomReference。它们分成了三种不同的级别,gc会在不同的情况下一一释放它们引用对象的空间。SoftReference
当我们希望对象的引用仍驻留在内存里面,直到内存出现不足时,gc会释放由SoftReference引用对象所占的内存空间。所以SoftReference可以用作Cache的实现。package io.github.klink; // containers/References.java // Demonstrates Reference objects import java.lang.ref.*; import java.util.*; class VeryBig { private static final int SIZE = 10000; private long[] la = new long[SIZE]; private String ident; public VeryBig(String id) { ident = id; } public String toString() { return ident; } protected void finalize() { 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; 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(); } System.gc(); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i = 0; i < size; i++) { checkQueue(); }
输出为:
Just created: java.lang.ref.SoftReference@5e1077 Just created: java.lang.ref.SoftReference@18b3364 Just created: java.lang.ref.SoftReference@1db05b2 Just created: java.lang.ref.SoftReference@530cf2 Just created: java.lang.ref.SoftReference@76fba0 Just created: java.lang.ref.SoftReference@181ed9e Just created: java.lang.ref.SoftReference@1175422 Just created: java.lang.ref.SoftReference@949f69 Just created: java.lang.ref.SoftReference@16dadf9 Just created: java.lang.ref.SoftReference@1b8d6f7
WeakReference
WeakReference并不会影响其引用对象的生命周期。换句话说,如果该对象只被WeakReference引用的话,它仍然会被gc回收。但是在gc回收之前,WeakReference会普通的引用没有区别,都可以访问引用对象的成员。WeakReference可用于:一个对象可能会有若干的引用,当我们不清楚这些引用是否仍在的时候,可以通过WeakReference引用该对象,如果该对象仍在内存中的话,WeakReference就可以获取对象的值,如果不在的话,WeakReference将会为Null。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(); } System.gc(); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i = 0; i < size; i++) { checkQueue(); }
输出结果为:
Just created: java.lang.ref.WeakReference@18b3364 Just created: java.lang.ref.WeakReference@1db05b2 Just created: java.lang.ref.WeakReference@530cf2 Just created: java.lang.ref.WeakReference@76fba0 Just created: java.lang.ref.WeakReference@181ed9e Just created: java.lang.ref.WeakReference@1175422 Just created: java.lang.ref.WeakReference@949f69 Just created: java.lang.ref.WeakReference@16dadf9 Just created: java.lang.ref.WeakReference@1b8d6f7 Just created: java.lang.ref.WeakReference@290fbc Finalizing Weak 9 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 0 In queue: null In queue: null In queue: null In queue: null In queue: null In queue: null In queue: null In queue: null In queue: null In queue: null
PhantomReference
PhantomReference与WeakReference一样,不会影响其引用对象的生命周期。PhantomReference与前两个Reference不同的是,它并不会引用对象,(这就是为什么使用PhantomReference的get()方法总是返回null的原因)。我们从它的构造函数可以看到,它有两个参数其中一个是ReferenceQueue,在gc回收时,会将PhantomReference引用的对象插入到ReferenceQueue中。但是在实际的代码执行过程中,并没有插入到ReferenceQueue,这点让我比较困惑。
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(); } System.gc(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i = 0; i < size; i++) { checkQueue(); }
输出结果为:
Just created: java.lang.ref.PhantomReference@5e1077 Just created: java.lang.ref.PhantomReference@18b3364 Just created: java.lang.ref.PhantomReference@1db05b2 Just created: java.lang.ref.PhantomReference@530cf2 Just created: java.lang.ref.PhantomReference@76fba0 Just created: java.lang.ref.PhantomReference@181ed9e Just created: java.lang.ref.PhantomReference@1175422 Just created: java.lang.ref.PhantomReference@949f69 Just created: java.lang.ref.PhantomReference@16dadf9 Just created: java.lang.ref.PhantomReference@1b8d6f7 Finalizing Phantom 9 Finalizing Phantom 8 Finalizing Phantom 7 Finalizing Phantom 6 Finalizing Phantom 5 Finalizing Phantom 4 Finalizing Phantom 3 Finalizing Phantom 2 Finalizing Phantom 1 Finalizing Phantom 0
ReferenceQueue
每一个Reference的实现都会有一个构造函数需要ReferenceQueue作为参数。当Reference的子类绑定一个ReferenceQueue时,Reference所指向的对象一旦被gc回收,gc会再回收之前将对象插入到ReferenceQueue中。WeakHashMap
WeakHashMap是基于WeakReference实现的一个Map。其特点是,WeakHashMap中的Key如果没有被任何对象引用的话,那么当gc回收垃圾的时候,这些未被引用的Key对应的记录会被删除。package io.github.klink; import java.util.*; 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; // Or, choose size via the command line: 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; // Save as "real" references map.put(k, v); } System.gc(); } }
输出结果为:
Finalizing Key 98 Finalizing Key 625 Finalizing Key 683 Finalizing Key 733 Finalizing Key 779 Finalizing Key 811 Finalizing Key 856 Finalizing Key 901 Finalizing Key 944 Finalizing Key 977 Finalizing Key 998 Finalizing Key 997 Finalizing Key 995 Finalizing Key 994 Finalizing Key 992 Finalizing Key 991 Finalizing Key 989 Finalizing Key 988 Finalizing Key 986 Finalizing Key 985 Finalizing Key 983 Finalizing Key 982 Finalizing Key 980 Finalizing Key 979 Finalizing Key 976 Finalizing Key 974 Finalizing Key 973 Finalizing Key 971 Finalizing Key 970 Finalizing Key 968
相关文章推荐
- ANDROID_MARS学习笔记_S04_009_用java.lang.ref.SoftReference作缓存,android.os.Handler和new Thread异步加载略图片
- java.lang.ref.Reference
- java.lang.ref.Reference
- java.lang.ref.Reference源代码分析
- java.lang.ref.FinalizerReference引发的内存泄漏
- Java学习总结4---java.lang.ref包探讨
- java.lang.IllegalArgumentException: Illegal group reference, replaceAll and dollar signs
- Error!]the type java.lang.object cannot be resolved. it is indirectly referenced from required .class files
- [Error!]the type java.lang.object cannot be resolved. it is indirectly reference
- eclipse:The type java.lang.Object cannot be resolved. It is indirectly referenced from required
- 深入探讨 java.lang.ref 包
- android开发问题:java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected imp
- JAVA基础(异常/深入java.lang.Throwable)
- android The type java.lang.Object cannot be resolved It is indirectly referenced ...
- java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut
- Struts2 DateTimepicker标签 和 java.lang.RuntimeException: Invalid action class configuration that references an unknown class named [YunWeiAction]
- The type java.lang.Object cannot be resolved.It is indirectly referenced from required.class files
- Java 的引用类使用(java.lang.ref包)指南
- java.lang.ref 的故事
- Eclipse error: The type java.lang.Object cannot be resolved. It is indirectly referenced from the required .class files