Java强引用、软引用、弱引用、虚引用详解

2017-01-12 10:05:53来源:作者:CSDN博客人点击

第七城市

学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码: 183993990 我们一起学Java!

Java中没有指针的概念,而引用就是一个弱化的指针,保证开发不能任意操作内存。最近整理了一下之前不明白的各种级别引用:强引用、软引用、弱引用、虚引用,它们的特点和应用场景汇总如下:

1、强引用

如果一个对象具有强引用,GC绝不会回收它;当内存空间不足,JVM宁愿抛出OutOfMemoryError错误。一般new出来的对象都是强引用,如下

//强引用 User strangeReference=new User();

2、软引用

如果一个对象具有软引用,当内存空间不足,GC会回收这些对象的内存,使用软引用构建敏感数据的缓存。

在JVM中,软引用是如下定义的,可以通过一个时间戳来回收,下面引自JVM:

public class SoftReference<T> extends Reference<T> { /** * Timestamp clock, updated by the garbage collector */ static private long clock; /** * Timestamp updated by each invocation of the get method. The VM may use * this field when selecting soft references to be cleared, but it is not * required to do so. */ private long timestamp; /** * Creates a new soft reference that refers to the given object. The new * reference is not registered with any queue. * * @param referent object the new soft reference will refer to */ public SoftReference(T referent) { super(referent); this.timestamp = clock; } /** * Creates a new soft reference that refers to the given object and is * registered with the given queue. * * @param referent object the new soft reference will refer to * @param q the queue with which the reference is to be registered, * or <tt>null</tt> if registration is not required * */ public SoftReference(T referent, ReferenceQueue<? super T> q) { super(referent, q); this.timestamp = clock; } /** * Returns this reference object's referent. If this reference object has * been cleared, either by the program or by the garbage collector, then * this method returns <code>null</code>. * * @return The object to which this reference refers, or * <code>null</code> if this reference object has been cleared */ public T get() { T o = super.get(); if (o != null && this.timestamp != clock) this.timestamp = clock; return o; }} 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

软引用的声明的借助强引用或者匿名对象,使用泛型SoftReference;可以通过get方法获得强引用。具体如下:

//软引用SoftReference<User>softReference=new SoftReference<User>(new User());strangeReference=softReference.get();//通过get方法获得强引用

3、弱引用

如果一个对象具有弱引用,在GC线程扫描内存区域的过程中,不管当前内存空间足够与否,都会回收内存,使用弱引用 构建非敏感数据的缓存。

在JVM中,弱引用是如下定义的,下面引自JVM:

public class WeakReference<T> extends Reference<T> { /** * Creates a new weak reference that refers to the given object. The new * reference is not registered with any queue. * * @param referent object the new weak reference will refer to */ public WeakReference(T referent) { super(referent); } /** * Creates a new weak reference that refers to the given object and is * registered with the given queue. * * @param referent object the new weak reference will refer to * @param q the queue with which the reference is to be registered, * or <tt>null</tt> if registration is not required */ public WeakReference(T referent, ReferenceQueue<? super T> q) { super(referent, q); }} 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 弱引用的声明的借助强引用或者匿名对象,使用泛型WeakReference<T>,具体如下: //弱引用WeakReference<User>weakReference=new WeakReference<User>(new User());

4、虚引用

如果一个对象仅持有虚引用,在任何时候都可能被垃圾回收,虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列联合使用,虚引用主要用来跟踪对象 被垃圾回收的活动。

在JVM中,虚引用是如下定义的,下面引自JVM:

public class PhantomReference<T> extends Reference<T> { /** * Returns this reference object's referent. Because the referent of a * phantom reference is always inaccessible, this method always returns * <code>null</code>. * * @return <code>null</code> */ public T get() { return null; } /** * Creates a new phantom reference that refers to the given object and * is registered with the given queue. * * <p> It is possible to create a phantom reference with a <tt>null</tt> * queue, but such a reference is completely useless: Its <tt>get</tt> * method will always return null and, since it does not have a queue, it * will never be enqueued. * * @param referent the object the new phantom reference will refer to * @param q the queue with which the reference is to be registered, * or <tt>null</tt> if registration is not required */ public PhantomReference(T referent, ReferenceQueue<? super T> q) { super(referent, q); }} 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 虚引用PhantomReference<T>的声明的借助强引用或者匿名对象,结合泛型ReferenceQueue<T>初始化,具体如下: //虚引用PhantomReference<User> phantomReference=new PhantomReference<User>(new User(),new ReferenceQueue<User>());

5、总结

下面是一段关于强引用、软引用、弱引用、虚引用的程序:

import java.lang.ref.*;import java.util.HashSet;import java.util.Set;class User { private String name; public User() {} public User(String name) { this.name=name; } @Override public String toString() { return name; } public void finalize(){ System.out.println("Finalizing ... "+name); }}/** * Created by jinxu on 15-4-25. */public class ReferenceDemo { private static ReferenceQueue<User> referenceQueue = new ReferenceQueue<User>(); private static final int size = 10; public static void checkQueue(){ /* Reference<? extends User> reference = null; while((reference = referenceQueue.poll())!=null){ System.out.println("In queue : "+reference.get()); }*/ Reference<? extends User> reference = referenceQueue.poll(); if(reference!=null){ System.out.println("In queue : "+reference.get()); } } public static void testSoftReference() { Set<SoftReference<User>> softReferenceSet = new HashSet<SoftReference<User>>(); for (int i = 0; i < size; i++) { SoftReference<User> ref = new SoftReference<User>(new User("Soft " + i), referenceQueue); System.out.println("Just created: " + ref.get()); softReferenceSet.add(ref); } System.gc(); checkQueue(); } public static void testWeaKReference() { Set<WeakReference<User>> weakReferenceSet = new HashSet<WeakReference<User>>(); for (int i = 0; i < size; i++) { WeakReference<User> ref = new WeakReference<User>(new User("Weak " + i), referenceQueue); System.out.println("Just created: " + ref.get()); weakReferenceSet.add(ref); } System.gc(); checkQueue(); } public static void testPhantomReference() { Set<PhantomReference<User>> phantomReferenceSet = new HashSet<PhantomReference<User>>(); for (int i = 0; i < size; i++) { PhantomReference<User> ref = new PhantomReference<User>(new User("Phantom " + i), referenceQueue); System.out.println("Just created: " + ref.get()); phantomReferenceSet.add(ref); } System.gc(); checkQueue(); } public static void main(String[] args) { testSoftReference(); testWeaKReference(); testPhantomReference(); }} 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

结果为

Just created: Soft 0Just created: Soft 1Just created: Soft 2Just created: Soft 3Just created: Soft 4Just created: Soft 5Just created: Soft 6Just created: Soft 7Just created: Soft 8Just created: Soft 9Just created: Weak 0Just created: Weak 1Just created: Weak 2Just created: Weak 3Just created: Weak 4Just created: Weak 5Just created: Weak 6Just created: Weak 7Just created: Weak 8Just created: Weak 9Finalizing ... Weak 7Finalizing ... Weak 8Finalizing ... Weak 9Finalizing ... Weak 4Finalizing ... Weak 5Finalizing ... Weak 6Finalizing ... Weak 0Finalizing ... Weak 1Finalizing ... Weak 2Finalizing ... Weak 3Finalizing ... Soft 9Finalizing ... Soft 8Finalizing ... Soft 7Finalizing ... Soft 6Finalizing ... Soft 5Finalizing ... Soft 4Finalizing ... Soft 3Finalizing ... Soft 2Finalizing ... Soft 1Finalizing ... Soft 0In queue : nullJust created: nullJust created: nullJust created: nullJust created: nullJust created: nullJust created: nullJust created: nullJust created: nullJust created: nullJust created: nullIn queue : nullFinalizing ... Phantom 9Finalizing ... Phantom 7Finalizing ... Phantom 8Finalizing ... Phantom 4Finalizing ... Phantom 5Finalizing ... Phantom 6Finalizing ... Phantom 0Finalizing ... Phantom 1Finalizing ... Phantom 2Finalizing ... Phantom 3

学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码: 183993990 我们一起学Java!

第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台