java reference详解_Java Reference详解
Reference是java中的引用類,它用來給普通對像進行包裝,從而在JVM在GC時,按照引用類型的不同,在回收時采用不同的邏輯。先來看下這個類的繼承體系:
image.png
在進行對這些子類進行分析解釋之前,我們先來看幾個概念:
對象的生命周期
image.png
1.創建階段(Created)
在創建階段系統通過下面的幾個步驟來完成對象的創建過程
為對象分配存儲空間
開始構造對象
從超類到子類對static成員進行初始化
超類成員變量按順序初始化,遞歸條用超類的構造方法
子類成員變量按順序初始化,子類構造方法調用
一旦對象被創建,并被分派給某些變量賦值,這個對象的狀態就切換到了應用階段。下面通過具體示例看看:
public class GrandParent {
public GrandParent(){
super();
System.out.println("GrandParent 構造函數");
}
{
System.out.println("GrandParent 成員代碼塊");
}
static {
System.out.println("GrandParent 靜態代碼塊");
}
}
public class Parent extends GrandParent {
public Parent() {
super();
System.out.println("Parent 構造函數");
}
{
System.out.println("Parent 成員代碼塊");
}
static {
System.out.println("Parent 靜態代碼塊");
}
}
public class Child extends Parent {
public Child() {
super();
System.out.println("Child 構造函數");
}
{
System.out.println("Child 成員代碼塊");
}
static {
System.out.println("Child 靜態代碼塊");
}
}
child為子類,parent為child的超類,GrandParent為超類的超類,當我們執行
Child child = new Child();
執行順序為:
image.png
當我們執行
Parent parent = new Parent();
執行順序為:
image.png
從而證明了一個對象創建階段的執行順序。
2.應用階段(In Use)
對象至少被一個強引用持有著。即上述例子中的child持有new Child()的強引用。
3.不可見階段(Invisible)
當一個對象處于不可見階段時,說明程序本身不再持有該對象的任何強引用,雖然這些引用是存在著的。簡單說就是程序的執行已經超出了該對象的作用域了。舉例來說:
image.png
則在此時稱之為count處于不可視階段。當然這種情況編譯器在編譯的過程中會直接報錯了。
4.不可達階段(Unreachable)
對象處于不可達階段是指該對象不再被任何強引用所持有。與"不可見階段"相比,"不可達階段"是指程序不再持有該對象的任何強引用,這種情況下,該對象仍可能被JVM等系統下的某些已裝載的靜態變量或線程或JNI等強引用持有著,這些特殊的強引用被稱為"GC root"。存在著這些GC root會導致對象的內存泄露情況,無法被回收。
5.收集階段(Collected)
當垃圾回收器發現該對象已經處于"不可達階段"并且垃圾回收起已經對該對象的內存空間重新分配做好準備時,則對象進入了"收集階段"。如果該對象已經重寫了finalize()方法,則會去執行該方法的終端操作。這里要注意盡量不要重載finalize()方法,原因有兩點:
會影響JVM的對象分配于回收速度
在分配該對象時,JVM需要在垃圾回收器上注冊該對象,以便在回收時能夠執行該重載方法;在該方法執行時需要消耗CPU時間且在執行完該方法后才會重新執行回收操作,即至少需要垃圾回收器對該對象執行兩次GC。
可能造成該對象的再次"復活"
在finalize()方法中,如果有其它的強引用再次持有該對象。則會導致對象的狀態由" 收集階段"又重新變為"應用階段"。這個已經破壞了Java對象的生命周期進程,且復活的對象不利于后續代碼管理。
終結階段(Finished)
當對象執行完finalize()方法后處于不可達狀態時,則該對象進入終結狀態。在該階段是等待垃圾回收器對該對象空間進行回收。
對象空間重分配階段(De-allocated)
垃圾回收器對該對象的所占用的內存空間進行回收或者再分配,則該對象測底消失了,稱之為"對象空重新分配階段"
對象可達性判斷
jvm 發生gc時,判斷一個對象是否存在引用,都是從根結合引用開始去標識,往往到達一個對象的引用路徑會很多,如下圖:
image.png
那么垃圾回收時會依據兩個原則來判斷對象的可達性:
單一路徑中,以最弱的引用為準
多路徑中,以最強的引用為準
例如Obj4的引用,存在:1>6、2>5、3>4,那么從根對象到Obj4的最強引用為2>5,因為它們都是強引用。如果僅僅村子一個路徑對Obj4有引用時,比如Obj4有引用時,比如現在只剩下1>6,那么根對象到Obj4的引用以最弱的為準。是軟引用。Obj4就是softly-reachable對象。
強引用(StrongReference)
強引用就是我們平時創建對象,創建數組時的引用。強引用在任何時候都不會被GC回收掉。例如
Parent parent = new Parent();
軟引用(SoftReference)
軟引用是在系統發生OOM之前才被JVM回收掉。軟引用常被用來對于內存敏感的緩存。
弱引用(WeakReference)
一旦JVM執行GC,弱引用就會被回收掉。
(虛引用)PhantomReference
虛引用主要作為其指向referent被回收時的一種通知機制。
總結
通過對SoftReference,WeakReference,PhantomReference,可以看出JDK提供這些類型的reference 主要是用來和GC交互的,根據reference的不同,讓JVM采用不同策略來進行對對象的回收(reclaim)。softly-reachable的referent在保證在OutOfMemoryError之前回收對象,weakly-reachable的referent在發生GC時就會被回收,。
總結
以上是生活随笔為你收集整理的java reference详解_Java Reference详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: gradle 指定java版本_Ecli
- 下一篇: java自带的xml解析_Java自带的