1. 程式人生 > 其它 >Java物件生命週期

Java物件生命週期

技術標籤:java

Java物件生命週期大致可以分為7個階段:

  1. 建立階段(Created)

  2. 應用階段(In Use)

  3. 不可見階段(Invisible)

  4. 不可到達階段(Unreachable)

  5. 可收集階段(Collected)

  6. 終結階段(Finalized)

  7. 釋放階段(De-allocated)

1.建立階段(Created)

	JVM 載入類的class檔案 此時所有的static變數和static程式碼塊將被執行
	載入完成後,對區域性變數進行賦值(先父後子的順序)
	再執行new方法 呼叫建構函式
	一旦物件被建立,並被分派給某些變數賦值,這個物件的狀態就切換到了應用階段

2.應用階段(In Use)

	物件至少被一個強引用持有著

3.不可見階段(Invisible)

當一個物件處於不可見階段時,說明程式本身不再持有該物件的任何強引用,但是這些引用可能還存在著,
//一般具體是指程式的執行已經超過該物件的作用域了。
boolean bool = false;
if(bool){
	int count =0;
	count++;
}
System.out.println(count);
	本地變數count在`System.out.println(count)`時已經超出了其作用域,則在此時稱之為count處於不可視階段。當然這樣的情況編譯器在編譯的過程中會直接報錯了。

4.不可到達階段(Unreachable)

	物件處於不可達階段是指該物件不再被任何強引用所持有,該物件仍可能被JVM等系統下的某些已裝載的靜態變數或執行緒或JNI等強引用持有著,這些特殊的強引用被稱為”GC root”。存在著這些GC root會導致物件的記憶體洩露情況,無法被回收。

5.可收集階段(Collected)

	當垃圾回收器發現該物件已經處於“不可達階段”而且垃圾回收器已經對該物件的記憶體空間又一次分配做好準備時,則物件進入了“收集階段”。假設該物件已經重寫了finalize()方法,則會去執行該方法的終端操作。

	注意:慎用finazlie()方法!原因有兩點:
	1.會影響JVM的物件分配與回收速度
	在分配該物件時,JVM須要在垃圾回收器上註冊該物件,以便在回收時可以執行該過載方法;在該方法的執行時須要消耗CPU時間且在執行完該方法後才會又一次執行回收操作,即至少須要垃圾回收器對該物件執行兩次GC。
	2.可能造成該物件的再次“復活”
	在finalize()方法中,假設有其他的強引用再次持有該物件,則會導致物件的狀態由“收集階段”又又一次變為“應用階段”。這個已經破壞了Java物件的生命週期程序,且“復活”的物件不利用興許的程式碼管理。

6.終結階段(Finalized)

	當物件執行完finalize()方法後仍然處於不可達狀態時,則該物件進入終結階段。在該階段是等待垃圾回收器對該物件空間進行回收。

7.釋放階段(De-allocated)

	物件空間又一次分配階段,垃圾回收器對該物件的所佔用的記憶體空間進行回收或者再分配了,則該物件徹底消失了,稱之為“物件空間又一次分配階段”。

類的載入機制

類的載入指的是將類的.class檔案中的二進位制資料讀入到記憶體中,將其放在執行時資料區的方法區內,然後在堆區建立一個java.lang.Class物件,用來封裝類在方法區內的資料結構。類的載入的最終產品是位於堆區中的Class物件,Class物件封裝了類在方法區內的資料結構,並且向Java程式設計師提供了訪問方法區內的資料結構的介面。

類載入器並不需要等到某個類被“首次主動使用”時再載入它,JVM規範允許類載入器在預料某個類將要被使用時就預先載入它,如果在預先載入的過程中遇到了.class檔案缺失或存在錯誤,類載入器必須在程式首次主動使用該類時才報告錯誤(LinkageError錯誤)如果這個類一直沒有被程式主動使用,那麼類載入器就不會報告錯誤

載入.class檔案的方式

  • 從本地系統中直接載入
  • 通過網路下載.class檔案
  • 從zip,jar等歸檔檔案中載入.class檔案
  • 從專有資料庫中提取.class檔案
  • 將Java原始檔動態編譯為.class檔案

類的生命週期

在這裡插入圖片描述

​ 類的生命週期

1.載入 點選檢視詳情

2.連線:包括驗證、準備和解析類的二進位制資料

驗證:確保被載入類的正確性
​ 當類被載入後,就進入驗證階段。連線就是把已經讀入到記憶體中的類的二進位制資料合併到JVM執行時環境中去。連線的第一步是類的驗證,其目的是保證被載入的類由正確的內部結構,並且與其他類協調一致。如果JVM檢查到錯誤,那麼就會丟擲相應的Error物件。

準備: 為類的靜態變數分配記憶體,並將其初始化為預設值
解析: 把類中的符號引用轉換成直接引用

3.初始化

如果一個類被直接引用,就會觸發類的初始化。在java中,直接引用的情況有:

  • 通過new關鍵字例項化物件、讀取或設定類的靜態變數、呼叫類的靜態方法。
  • 通過反射方式執行以上三種行為。
  • 初始化子類的時候,會觸發父類的初始化。
  • 作為程式入口直接執行時(也就是直接呼叫main方法)。
  • 除了以上四種情況,其他使用類的方式叫做被動引用,而被動引用不會觸發類的初始化。

4.解除安裝

在類使用完之後,如果滿足下面的情況,類就會被解除安裝:

  • 該類所有的例項都已經被回收,也就是java堆中不存在該類的任何例項。
  • 載入該類的ClassLoader已經被回收
  • 該類對應的java.lang.Class物件沒有任何地方被引用,無法在任何地方通過反射- 訪問該類的方法