成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 中的四種引用

開發(fā) 后端
當 Java 中引用的對象越來越多,會導致內存空間不足,最終會產生錯誤 OutOfMemoryError,并讓應用程序終止。那為什么 GC 在此時不能多收集一些對象呢?這就和今天說的引用類型有關了。

之前我們提到過 GC,但當 Java 中引用的對象越來越多,會導致內存空間不足,最終會產生錯誤 OutOfMemoryError,并讓應用程序終止。那為什么 GC 在此時不能多收集一些對象呢?這就和今天說的引用類型有關了。

首先,從 JDK1.2 開始,對象的引用被劃分為4種級別,從而使程序能更加靈活地控制對象的生命周期。這4種級別由高到低依次為:強引用、軟引用、弱引用和虛引用。

強引用

強引用(Strong Reference)是使用最普遍的引用。如果一個對象具有強引用,那么它永遠不會被 GC。例如:

  1. Object strongReference = new Object(); 

當內存空間不足時,JVM 寧愿拋出OutOfMemoryError,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足的問題。

如果強引用對象不使用時,需要弱化從而可以被 GC,例如ArrayList中的clear()方法:

  1. /** 
  2. * Removes all of the elements from this list. The list will 
  3. * be empty after this call returns. 
  4. */ 
  5. public void clear() { 
  6. modCount++; 
  7.  
  8. // clear to let GC do its work 
  9. for (int i = 0; i < size; i++) 
  10. elementData[i] = null; 
  11.  
  12. size = 0

顯式地設置強引用對象為null,或讓其超出對象的生命周期范圍,則垃圾回收器認為該對象不存在引用,就會回收這個對象。具體什么時候收集這要取決于具體的垃圾回收器。

軟引用

如果一個對象只具有軟引用(Soft Reference),當內存空間充足時,垃圾回收器就不會回收它;如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。讓我們來看一個例子具體了解一下:

  1. String str = new String("abc"); 
  2. SoftReference<String> softReference = new SoftReference<>(str); 
  3. String result = softReference.get(); 

讓我們來看一下get():

  1. public T get() { 
  2. o = super.get(); 
  3. // timestamp代表上一次軟引用上一次被使用的時間(初始化、get()) 
  4. // clock代表上一次GC的時間 
  5. if (o != null && this.timestamp != clock) 
  6. this.timestamp = clock
  7. return o; 

因此,軟引用在被垃圾回收時,也遵循LRU法則,優(yōu)先回收最近最少被使用的對象進行回收。

軟引用的使用場景多是內存敏感的高速緩存。具體來說,就是我們希望將數(shù)據(jù)存放到緩存中,這樣可以快速進行讀取。但是,當 JVM 中內存不夠用時,我們又不希望緩存數(shù)據(jù)會占用到 JVM 的內存。例如配合ReferenceQueue,如果軟引用所引用對象被垃圾回收,JVM 就會把這個軟引用加入到與之關聯(lián)的引用隊列中:

  1. ReferenceQueue<String> referenceQueue = new ReferenceQueue<>(); 
  2. String str = new String("abc"); 
  3. SoftReference<String> softReference = new SoftReference<>(str, referenceQueue); 
  4.  
  5. str = null
  6. // Notify GC 
  7. System.gc(); 
  8.  
  9. System.out.println(softReference.get()); // abc 
  10.  
  11. Reference<? extends String> reference = referenceQueue.poll(); 
  12. System.out.println(reference); //null 

但是需要注意的是,如果使用軟引用緩存,有可能導致Full GC增多。

弱引用

如果一個對象只具有弱引用(Weak Reference),其生命周期相比于軟引用更加短暫。在垃圾回收器線程掃描它所管轄的內存區(qū)域的過程中,一旦發(fā)現(xiàn)了只具有弱引用的對象,不管當前內存空間足夠與否,都會對它進行回收。不過,由于垃圾回收器是一個優(yōu)先級很低的線程,因此不一定會很快發(fā)現(xiàn)那些只具有弱引用的對象。其使用為:

  1. String str = new String("abc"); 
  2. WeakReference<String> weakReference = new WeakReference<>(str); 
  3. str = weakReference.get(); 

講到弱引用,就不得不提到WeakHashMap。和HashMap相比,當我們給 JVM 分配的內存不足的時候,HashMap 寧可拋出 OutOfMemoryError 異常,也不會回收其相應的沒有被引用的對象,而 WeakHashMap 則會回收存儲在其中但有被引用的對象。

WeakHashMap 通過將一些沒有被引用的鍵的值賦值為 null ,這樣的話就會告知GC去回收這些存儲的值了。假如我們特地傳入 key 為 null 的鍵,WeakHashMap 會將鍵設置為特殊的 Oject,源碼為:

  1. public V put(K key, V value) { 
  2. // key會被重新賦值 
  3. Object k = maskNull(key); 
  4. int h = hash(k); 
  5. Entry<K,V>[] tab = getTable(); 
  6. int i = indexFor(h, tab.length); 
  7.  
  8. for (Entry<K,V> e = tab[i]; e != null; ee = e.next) { 
  9. if (h == e.hash && eq(k, e.get())) { 
  10. oldValue = e.value; 
  11. if (value != oldValue) 
  12. e.value = value; 
  13. return oldValue; 
  14.  
  15. modCount++; 
  16. Entry<K,V> e = tab[i]; 
  17. tab[i] = new Entry<>(k, value, queue, h, e); 
  18. if (++size >= threshold) 
  19. resize(tab.length * 2); 
  20. return null; 
  21.  
  22. /** 
  23. * Value representing null keys inside tables. 
  24. * 特殊的key 
  25. */ 
  26. private static final Object NULL_KEY = new Object(); 
  27.  
  28. /** 
  29. * Use NULL_KEY for key if it is null. 
  30. */ 
  31. private static Object maskNull(Object key) { 
  32. return (key == null) ? NULL_KEY : key; 

虛引用

虛引用(PhantomReference),顧名思義,就是形同虛設。與其他幾種引用都不同,虛引用并不會決定對象的生命周期。如果一個對象僅持有虛引用,那么它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。

虛引用主要用來跟蹤對象被垃圾回收器回收的活動。 虛引用與軟引用和弱引用的一個區(qū)別在于:

虛引用必須和引用隊列(ReferenceQueue)聯(lián)合使用。當垃圾回收器準備回收一個對象時,如果發(fā)現(xiàn)它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之關聯(lián)的引用隊列中。

例如:

  1. String str = new String("abc"); 
  2. ReferenceQueue queue = new ReferenceQueue(); 
  3. // 創(chuàng)建虛引用,要求必須與一個引用隊列關聯(lián) 
  4. PhantomReference pr = new PhantomReference(str, queue); 

程序可以通過判斷引用隊列中是否已經加入了虛引用,來了解被引用的對象是否將要進行垃圾回收。如果程序發(fā)現(xiàn)某個虛引用已經被加入到引用隊列,那么就可以在所引用的對象的內存被回收之前采取必要的行動,也可以理解為一種回調方法。

總結

Java 中4種引用的級別和強度由高到低依次為:強引用 -> 軟引用 -> 弱引用 -> 虛引用

通過表格,說明其特性:

Java 中的四種引用

責任編輯:趙寧寧 來源: 今日頭條
相關推薦

2011-11-24 16:34:39

Java

2021-10-18 15:50:49

Android強引用軟引用

2023-05-22 08:03:28

JavaScrip枚舉定義

2011-12-30 13:15:53

Java

2009-06-11 17:22:03

操作xml方式Java

2020-06-17 08:31:10

權限控制Spring Secu

2021-07-27 10:49:10

SpringSecurity權限

2017-07-06 15:40:19

DevOps核心能力

2012-09-11 09:55:26

編程HTML5編程能力

2011-03-16 09:05:53

NATiptables

2021-08-25 12:55:33

Linuxcron

2009-06-22 11:01:12

2010-07-08 11:20:13

UML動態(tài)建模

2021-10-24 08:37:18

網絡監(jiān)控網絡架構網絡

2022-08-14 16:04:15

機器學習數(shù)據(jù)集算法

2020-07-24 09:56:12

React開發(fā)數(shù)據(jù)

2011-06-22 15:21:08

XML

2009-03-31 13:12:30

解析XMLJava

2024-05-21 14:04:16

2012-02-22 11:13:53

Java
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产a区 | 国产成人精品视频 | 91精品国产手机 | 日韩av第一页 | 91精品综合久久久久久五月天 | 精品国产精品三级精品av网址 | 久久亚洲国产精品日日av夜夜 | 成人免费观看视频 | 国产视频久久 | 亚洲国产精品久久 | 久久看精品 | 国产一区二区三区视频 | 99精品视频免费在线观看 | 91精品中文字幕一区二区三区 | 毛片久久久 | 色综合激情| av在线成人 | 黑人巨大精品 | 日本黄色短片 | 久久国产综合 | 91精品国产综合久久精品 | 在线观看视频h | 尤物视频在线免费观看 | 久久99精品久久久久久 | av看片网站 | 综合久久99 | 亚洲精品久久久一区二区三区 | 免费黄色大片 | 欧美精品福利 | 日韩精品一区二区久久 | 成人毛片视频免费 | 亚洲一区二区三区免费视频 | 久久精品| 精品国产乱码久久久久久丨区2区 | 日韩成人精品在线观看 | 另类一区| 性一交一乱一透一a级 | 亚洲欧美日韩精品久久亚洲区 | 国产成人精品一区二区三区在线观看 | 天天综合日日夜夜 | 国产中文字幕在线观看 |