Java強(qiáng)引用、軟引用、弱引用、虛引用詳解
來(lái)源:程序員人生 發(fā)布時(shí)間:2017-02-06 08:09:23 閱讀次數(shù):4200次
學(xué)習(xí)Java的同學(xué)注意了!!!
學(xué)習(xí)進(jìn)程中遇到甚么問(wèn)題或想獲得學(xué)習(xí)資源的話,歡迎加入Java學(xué)習(xí)交換群,群號(hào)碼:183993990 我們1起學(xué)Java!
Java中沒(méi)有指針的概念,而援用就是1個(gè)弱化的指針,保證開(kāi)發(fā)不能任意操作內(nèi)存。最近整理了1下之前不明白的各種級(jí)別援用:強(qiáng)援用、軟援用、弱援用、虛援用,它們的特點(diǎn)和利用場(chǎng)景匯總以下:
1、強(qiáng)援用
如果1個(gè)對(duì)象具有強(qiáng)援用,GC絕不會(huì)回收它;當(dāng)內(nèi)存空間不足,JVM寧愿拋出OutOfMemoryError毛病。1般new出來(lái)的對(duì)象都是強(qiáng)援用,以下
User strangeReference=new User();
2、軟援用
如果1個(gè)對(duì)象具有軟援用,當(dāng)內(nèi)存空間不足,GC會(huì)回收這些對(duì)象的內(nèi)存,使用軟援用構(gòu)建敏感數(shù)據(jù)的緩存。
在JVM中,軟援用是以下定義的,可以通過(guò)1個(gè)時(shí)間戳來(lái)回收,下面引自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
軟援用的聲明的借助強(qiáng)援用或匿名對(duì)象,使用泛型SoftReference;可以通過(guò)get方法取得強(qiáng)援用。具體以下:
SoftReference<User>softReference=new SoftReference<User>(new User());
strangeReference=softReference.get();
3、弱援用
如果1個(gè)對(duì)象具有弱援用,在GC線程掃描內(nèi)存區(qū)域的進(jìn)程中,不管當(dāng)前內(nèi)存空間足夠與否,都會(huì)回收內(nèi)存,使用弱援用 構(gòu)建非敏感數(shù)據(jù)的緩存。
在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
弱援用的聲明的借助強(qiáng)援用或匿名對(duì)象,使用泛型WeakReference<T>,具體以下:
WeakReference<User>weakReference=new WeakReference<User>(new User());
4、虛援用
如果1個(gè)對(duì)象僅持有虛援用,在任什么時(shí)候候都可能被垃圾回收,虛援用與軟援用和弱援用的1個(gè)區(qū)分在于:虛援用必須和援用隊(duì)列聯(lián)合使用,虛援用主要用來(lái)跟蹤對(duì)象 被垃圾回收的活動(dòng)。
在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>的聲明的借助強(qiáng)援用或匿名對(duì)象,結(jié)合泛型ReferenceQueue<T>初始化,具體以下:
PhantomReference<User> phantomReference=new PhantomReference<User>(new User(),new ReferenceQueue<User>());
5、總結(jié)
下面是1段關(guān)于強(qiáng)援用、軟援用、弱援用、虛援用的程序:
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
生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)