Java強引用、ソフト引用、弱引用、虚引用の詳細
10200 ワード
************************************************************************************************声明を出して********を**します。
オリジナル作品は、「暁風残月xj」のブログから来ました。転載を歓迎します。転載する時は必ず出典を明記してください。http://blog.csdn.net/xiaofengcanyuexjを選択します
様々な原因のため、多くの不足があるかもしれません。斧を歓迎します。
**********
******************************************************************************************
Javaにはポインターの概念がなく、参照は弱化のポインターであり、開発が任意にメモリを操作できないことを保証する。最近はよく分からないレベルの引用を整理しました。強引用、ソフト引用、弱引用、虚引用、それらの特徴と応用シーンは以下のようにまとめられています。
1、強引用 強い引用がある場合、GCはそれを回収しません。メモリの空間が足りない時、JVMはむしろOutOfMemoryErrエラーを投げます。一般的にnewの対象は強い引用です。以下の通りです。
2、ソフト引用 オブジェクトがソフト参照を持っている場合、メモリ空間が足りない場合、GCはこれらのオブジェクトのメモリを回収し、ソフト参照を使用して敏感データのキャッシュを構築する。
JVMではソフト引用は以下のように定義されています。タイムスタンプで回収できます。以下はJVMから引用します。
ソフト引用の声明は強い引用または匿名の対象によって、汎型ソフトReference<T>を使用する。get法により強い参照が得られます。具体的には以下の通りです
JVMでは弱引用は以下のように定義されており、以下はJVMから引用される。
JVMにおいて、虚引用は以下のように定義されており、以下はJVMから引用される。
PhotomReference<T>の声明を引用することは、強引用または匿名の対象によって、汎型ReferenceQue<T>を初期化し、具体的には以下の通りである。
強引用、ソフト引用、弱引用、虚引用に関する手順は以下の通りです。
時間が限られているので、ブログを書いている間に文献を参考にしました。ありがとうございます。同時にレベルの原因にかんがみて、どうしても足りないところがあります。斧を歓迎します。
オリジナル作品は、「暁風残月xj」のブログから来ました。転載を歓迎します。転載する時は必ず出典を明記してください。http://blog.csdn.net/xiaofengcanyuexjを選択します
様々な原因のため、多くの不足があるかもしれません。斧を歓迎します。
**********
******************************************************************************************
Javaにはポインターの概念がなく、参照は弱化のポインターであり、開発が任意にメモリを操作できないことを保証する。最近はよく分からないレベルの引用を整理しました。強引用、ソフト引用、弱引用、虚引用、それらの特徴と応用シーンは以下のようにまとめられています。
1、強引用 強い引用がある場合、GCはそれを回収しません。メモリの空間が足りない時、JVMはむしろOutOfMemoryErrエラーを投げます。一般的に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;
}
}
ソフト引用の声明は強い引用または匿名の対象によって、汎型ソフトReference<T>を使用する。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);
}
}
弱い引用の声明は強い引用または匿名の対象によって汎型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);
}
}
PhotomReference<T>の声明を引用することは、強引用または匿名の対象によって、汎型ReferenceQue<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();
}
}
結果はJust created: Soft 0
Just created: Soft 1
Just created: Soft 2
Just created: Soft 3
Just created: Soft 4
Just created: Soft 5
Just created: Soft 6
Just created: Soft 7
Just created: Soft 8
Just created: Soft 9
Just created: Weak 0
Just created: Weak 1
Just created: Weak 2
Just created: Weak 3
Just created: Weak 4
Just created: Weak 5
Just created: Weak 6
Just created: Weak 7
Just created: Weak 8
Just created: Weak 9
Finalizing ... Weak 7
Finalizing ... Weak 8
Finalizing ... Weak 9
Finalizing ... Weak 4
Finalizing ... Weak 5
Finalizing ... Weak 6
Finalizing ... Weak 0
Finalizing ... Weak 1
Finalizing ... Weak 2
Finalizing ... Weak 3
Finalizing ... Soft 9
Finalizing ... Soft 8
Finalizing ... Soft 7
Finalizing ... Soft 6
Finalizing ... Soft 5
Finalizing ... Soft 4
Finalizing ... Soft 3
Finalizing ... Soft 2
Finalizing ... Soft 1
Finalizing ... Soft 0
In queue : null
Just created: null
Just created: null
Just created: null
Just created: null
Just created: null
Just created: null
Just created: null
Just created: null
Just created: null
Just created: null
In queue : null
Finalizing ... Phantom 9
Finalizing ... Phantom 7
Finalizing ... Phantom 8
Finalizing ... Phantom 4
Finalizing ... Phantom 5
Finalizing ... Phantom 6
Finalizing ... Phantom 0
Finalizing ... Phantom 1
Finalizing ... Phantom 2
Finalizing ... Phantom 3
プログラムの実行結果から、虚引用は虚構のように見えます。参照対象はいつでもごみ箱に回収され、弱い引用の対象は少し長いライフサイクルを持っています。ごみ箱が回収操作を実行すると、ごみ箱に回収される可能性があります。ソフト参照の対象はより長いライフサイクルを持っています。しかし、Java仮想マシンではメモリが足りないと判断した場合、ゴミ回収機に回収されます。時間が限られているので、ブログを書いている間に文献を参考にしました。ありがとうございます。同時にレベルの原因にかんがみて、どうしても足りないところがあります。斧を歓迎します。