05.22 java中四種引用!

Java內存管理包括內存分配和內存回收。

  • 內存分配:程序員通過new對象,JVM會自動為該對象分配內存。
  • 內存回收:Java在JVM虛擬機上增加了垃圾回收(Garbage Collection)機制,用以在合適的時間觸發垃圾回收,將不需要的內存空間回收釋放,避免無限制的內存增長導致的OOM.

其實GC時主要看這個對象是否有引用指向該對象。按照這種引用的強弱的關係, 從JDK1.2版本開始,把對象的引用分為四種級別,從而使程序能更加靈活的控制對象的生命週期。這四種級別由高到低依次為:強引用、軟引用、弱引用和虛引用。

四種引用

  1. 強引用(StrongReference)
  • 是指創建一個對象並把這個對象賦給一個引用變量。比如 Object tv = new Object();
  • 強引用有引用變量指向時永遠不會被垃圾回收,JVM寧願拋出OutOfMemory錯誤也不會回收這種對象。
  • 如果程序確實不在用到某個強引用變量,通常可以手動將這個引用指向賦值為null。比如常見的集合中 claer() 方法。下面這段代碼就是 ArrayList 的 clear()
/**
* Removes all of the elements from this list. The list will
* be empty after this call returns.
*/
public void clear() {
modCount++;

// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;

size = 0;
}

2.軟引用(SoftReference)

SoftReference softRef = new SoftReference<>(T t);
softRef.get()

3.弱引用(WeakReference)

WeakReference weakRef = new WeakReference<>(T t);
weakRef.get()

4.虛引用(PhantomReferece)

  • 顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定對象的生命週期。
  • 任何時候都可以被GC回收,引用是最弱的。
  • ReferenceQueue queue = new ReferenceQueue ();
  • PhantomReference pr = new PhantomReference (object, queue);
  • 由於引用關係最弱,並且源碼中的get方法直接返回null,所以必須配合ReferenceQueue使用
public T get() {
return null;
}

Q:Android中為什麼不推薦使用軟引用(SoftReference)?

Avoid Soft References for Caching

In practice, soft references are inefficient for caching. The runtime doesn't have enough information on which references to clear and which to keep. Most fatally, it doesn't know what to do when given the choice between clearing a soft reference and growing the heap.

在實踐中,軟引用(soft references)在緩存中是低效的,因為runtime並沒有足夠的信息來判別應該清除或者保留哪個 SoftReference(持有的對象),更無法判定當 App 要求更多內存的時候,是應該清除 SoftReference,還是增大 App 的Heap。

The lack of information on the value to your application of each reference limits the usefulness of soft references. References that are cleared too early cause unnecessary work; those that are cleared too late waste memory.

你的程序的引用的信息的缺失導致軟引用用處的侷限性。過早清除的引用會導致無用功,太晚清除又會浪費內存。

Most applications should use an android.util.LruCache instead of soft references. LruCache has an effective eviction policy and lets the user tune how much memory is allotted.

大多數程序應該使用android.util.LruCache來替代軟引用,LruCache有著更高效的回收策略,並讓用戶協調要分配多少內存。

Q:如果一個對象同時有強引用和弱引用與之關聯,那GC的時候會回收嗎?

\t偽代碼
T t = new T();
WeakReference tRef = new WeakReference<>(t);

很顯然GC的時候這個t不僅有弱引用還有強引用關聯,此時是不會回收的。

Q: 既然虛引用形同虛設,那麼它有什麼作用?

網上找這樣的描述:

  1. Use Cases
  2. There’re two common use-cases they are used for.
  3. The first technique is to determine when an object was removed from the memory which helps to schedule memory-sensitive tasks. For example, we can wait for a large object to be removed before loading another one.
  4. The second practice is to avoid using the finalize method and improve the finalization process.

第一個就是能夠知道這個對象回收時機,能在對象被GC時收到系統通知

第二個就是避免使用 finalize

由於目前沒有真正用過虛引用,歡迎補充,多謝~~


分享到:


相關文章: