在Java裡, 當一個物件被創建時, 它被放在記憶體堆裡. 當GC運行的時候, 如果發現沒有任何引用指向該物件, 該物件就會被回收以騰出記憶體空間。
或換句話說, 一個物件被回收, 必須滿足兩個條件:
1)沒有任何引用指向它 (建議學習:java課程)
2)GC被運行。
Java對於簡單的情況, 手動置空是不需要程式設計師來做的, 因為在java中, 對於簡單物件, 當呼叫它的方法執行完畢後, 指向它的引用會被GC回收,
實際中我們寫程式碼,往往是透過把所有指向某個物件的referece置null實現,如:
Person p = new Person("张三",18,"男");//强引用 ... p=null;//不再使用的时候置null
很明顯,手動置null物件對於程式設計師來說,是一件繁瑣且違背自動回收機制的。
Java對於簡單的情況, 如方法中的產生的局部對象,是不需要程式設計師來手動置空, 當呼叫它的方法執行完畢後, 指向它的引用會被GC回收。
而複雜一點的情況,例如使用cache,因為cache的物件正是程式運行需要的,那麼只要程式正在執行, cache中的引用就不會被GC,那麼隨著cache中的引用越來越多, GC無法回收的物件也越來越多,無法被自動回收,此時就必須有開發者來進行處理回收,顯然也違反了java自動回收機制。
對此,java引入了弱引用(WeakReference)。
當一個物件只是被weak reference指向, 而沒有任何其他strong reference指向的時候, 如果GC運行, 那麼這個物件就會被回收。如果存在強引用同時與之關聯,則進行垃圾回收時也不會回收該物件。
WeakReference的語法:
WeakReference<T> weakReference = new WeakReference<T>(referent);
當要獲得weak reference引用的物件時, 首先需要判斷它是否已經被回收:
weakReference.get();
如果此方法為空, 那麼說明weakReference所指向的物件已經被回收了。
下面一個WeakReference的栗子:
Person類別:
package com.yx.test.model; /** * Person * * @author yx * @date 2019/11/26 16:28 */ public class Person { private String name; private int age; private String sex; public Person() { } public Person(String name, int age, String sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
測試類別TestWeakReference:
package com.yx.test.reference; import com.yx.test.model.Person; import java.lang.ref.WeakReference; /** * TestWeakReference * * @author yx * @date 2019/11/26 16:30 */ public class TestWeakReference { public static void main(String[] args) { Person p = new Person("张三",18,"男"); WeakReference<Person> weakPerson = new WeakReference<Person>(p); int i=0; while(true){ if(weakPerson.get()!=null){ i++; System.out.println("Object is alive for "+i+" loops - "+weakPerson); }else{ System.out.println("Object has been collected."); break; } } } }
運行結果:
p is alive for 1 loops - java.lang.ref.WeakReference@330bedb4 ... p is alive for 62331 loops - java.lang.ref.WeakReference@330bedb4 p is alive for 62332 loops - java.lang.ref.WeakReference@330bedb4 p has been collected.
可以看到,在while循環執行數萬次後,p被回收了。
多次測試運行程序,發現p回收時循環執行的次數是不確定的,這個很容易理解:因為這是由GC運行的不確定性所決定的。
小結:
1.Java中當一個物件只被一個弱引用引用時,如果GC運行, 那麼這個物件就會被回收。
2.弱引用的一個特點是它何時被回收是不可確定的;
以上是java弱引用的理解與使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!