Java强引用、软引用、弱引用、虚引用详解
来源:程序员人生 发布时间:2017-02-06 08:09:23 阅读次数:3785次
学习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
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠