Java強引用、軟引用、弱引用、虛引用詳解
來源:程序員人生 發布時間:2017-02-06 08:09:23 閱讀次數:4211次
學習Java的同學注意了!!!
學習進程中遇到甚么問題或想獲得學習資源的話,歡迎加入Java學習交換群,群號碼:183993990 我們1起學Java!
Java中沒有指針的概念,而援用就是1個弱化的指針,保證開發不能任意操作內存。最近整理了1下之前不明白的各種級別援用:強援用、軟援用、弱援用、虛援用,它們的特點和利用場景匯總以下:
1、強援用
如果1個對象具有強援用,GC絕不會回收它;當內存空間不足,JVM寧愿拋出OutOfMemoryError毛病。1般new出來的對象都是強援用,以下
User strangeReference=new User();
2、軟援用
如果1個對象具有軟援用,當內存空間不足,GC會回收這些對象的內存,使用軟援用構建敏感數據的緩存。
在JVM中,軟援用是以下定義的,可以通過1個時間戳來回收,下面引自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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 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();
3、弱援用
如果1個對象具有弱援用,在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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 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、虛援用
如果1個對象僅持有虛援用,在任什么時候候都可能被垃圾回收,虛援用與軟援用和弱援用的1個區分在于:虛援用必須和援用隊列聯合使用,虛援用主要用來跟蹤對象 被垃圾回收的活動。
在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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 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、總結
下面是1段關于強援用、軟援用、弱援用、虛援用的程序:
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);
}
}
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 = 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();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 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
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈