Java的GC相關

爲什麼要GC

    Java不像C++一樣,對於在堆上申請的空間需要調用free或者delete這樣手動釋放,而是使用gc來進行自動的釋放,對於一個應用程序來說,給定的堆的空間是一定的,如果無限的申請但是不釋放的話,就會導致oom,因此gc很重要。

什麼需要被GC

    和c++一樣,在堆上申請的內存空間的對象需要在一個合適的時間釋放,回想在C++中的智能指針,往往就是在對某個對象的引用計數爲0時執行析構函數釋放對應的內存,java中也是一樣,當對於某個對象的引用爲0時會被gc。

Java的引用對象

  • 強引用

一般情況下聲明的都是強引用,例如:

Person person = new Person();

  注意這裏的new Person()是一個對象,是在堆上分配了一定內存大小的,而person是指向它的引用,這裏就是強引用。

  對於一個對象來說,只要有強引用指向它的話,系統是肯定不會對它執行gc的。所以如果在一個函數中如上正常創建一個對象的話,只有在函數執行完之後,該對象纔回被gc,因爲變量person的生命週期到頭了,就沒有指向Person對象的引用了。對於全局變量來說,如果想釋放它的話,就需要將person = null,這樣也會去掉該對象的引用。

  • 弱引用

弱引用的聲明如下

WeakReference<Person> weakref = new WeakReference<>(person);

這樣就會將指向Person對象的引用變爲弱引用了

Person person = weakref.get()

這樣又會轉換爲強引用

對於一個對象來說,如果它的所有引用都是弱引用的話就會被立刻gc

  • 軟引用

軟引用的聲明如下

SoftReference<Person> softref = new SoftReference<>(person)

轉爲強引用的方法如上

對於一個對象來說,如果它的所有引用都是軟引用且當前內存空間不足時,系統會對其gc

  • 虛引用

虛引用需要和ReferenceQueue聯合使用,具體如下

ReferenceQueue rq = new ReferenceQueue();

PhantomReference<Person> phantomref = new PhantomReference<>(person,rq);

關於ReferenceQueue還需要再研究一下,網上說可以用來實現當某個對象被gc時的通知,未完。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章