日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java中对象的生存期_Java中对象的生存周期

發(fā)布時間:2023/12/18 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java中对象的生存期_Java中对象的生存周期 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

JAVA對象的生存周期

1.創(chuàng)建階段(Created)

為對象分配內(nèi)存需要考慮的問題

2.應用階段(In Use)

3.不可見階段(Invisible)

4.不可達階段(Unreachable)

5.收集階段(Collected)

6.終結階段

7.對象空間重新分配階段

JAVA對象的生存周期

在Java中,對象的生命周期包括以下幾個階段:

創(chuàng)建階段(Created)

應用階段(In Use)

不可見階段(Invisible)

不可達階段(Unreachable)

收集階段(Collected)

終結階段(Finalized)

對象空間重分配階段(De-allocated)

1.創(chuàng)建階段(Created)

在創(chuàng)建階段系統(tǒng)通過下面的幾個步驟來完成對象的創(chuàng)建過程

虛擬機遇到new指令,首先去檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號引用。

檢查符號引用的類是否引進被加載,如果沒有被加載,則執(zhí)行相應的類加載過程。

為對象分配內(nèi)存(為對象分配的內(nèi)存大小在類加載時已經(jīng)確定)(為對象分配內(nèi)存還有一點知識點我在后面贅述)

開始構造對象

從超類到子類對static成員進行初始化

超類成員變量按順序初始化,遞歸調(diào)用超類的構造方法

子類成員變量按順序初始化,子類構造方法調(diào)用

一旦對象被創(chuàng)建,并被分派給某些變量賦值,這個對象的狀態(tài)就切換到了應用階段

Java對象的創(chuàng)建這里涉及到知識點儲備需要知道,下面這些基本的知識,下面點擊鏈接可以自行查閱。

JVM內(nèi)存區(qū)域劃分

JVM類生命周期概述:加載時機與加載過程

為對象分配內(nèi)存需要考慮的問題

問題一:堆內(nèi)存的分配方式

為對象分配內(nèi)存時,對象需要的內(nèi)存大小在類加載時就已經(jīng)確定,這里為對象分配空間的任務相當于把一塊確定大小的內(nèi)存從堆中劃分出來。而堆內(nèi)存的分配方式是我們這里要說的第一個問題:

分配方式一:指針碰撞

假設JVM中堆的內(nèi)存是絕對規(guī)整的,空閑的內(nèi)存在一遍,已經(jīng)被使用的內(nèi)存在一遍,中間由一個指針進行分割。那么對象的內(nèi)存分配就由將指針移動即可。

分配方式二:空閑列表法

如果JVM中堆的內(nèi)存不是規(guī)整的,空閑的內(nèi)存和被使用的內(nèi)存相互交錯。這時虛擬機需要維護一個列表,記錄哪塊內(nèi)存時空閑的,當對象需要被分配內(nèi)存時,找到一塊足夠大的內(nèi)存分配。

**考慮分配方式取決于JVM堆內(nèi)存是否規(guī)整,而JVM內(nèi)存是否規(guī)整取決于JVM使用的垃圾回收器是否帶有垃圾整理功能。**例如:在使用Serial、ParNew 等帶Compact過程的收集器時,系統(tǒng)采用的分配算法是指針碰撞;而使用CMS這種基于Mark-Sweep算法的收集器時,通常采用空閑列表。

問題二:考慮對象是否被頻繁創(chuàng)建,線程安全問題

即使是修改一個指正,但是在并發(fā)的情況下也不是安全的。可能存在對象A正在分配的,可能出現(xiàn)正在給對象A分配內(nèi)存,指針還沒來得及修改,對象B又同時使用了原來的指針來分配內(nèi)存的情況。解決這個問題有兩種方案:

第一種:是對分配內(nèi)存空間的動作進行同步處理,實際上虛擬機采用CAS配上失敗重試的方式保證更新操作的原子性:

第二種:是把內(nèi)存分配的動作按照線程劃分在不同的空間之中進行,:即每個線程在Java堆中預先分配小塊內(nèi)存,稱為本地線程分配緩沖(Thread Local Allocation Buffer, TLAB)。 哪個線程要分配內(nèi)存,就在哪個線程的TLAB上分配,只有TLAB用完并分配新的FLAB時,才需要同步鎖定。虛擬機是否使用TLAB,可以通過-XX:+/-UseTLAB參數(shù)來設定。

內(nèi)存分配完成后,虛擬機需要將分配到的內(nèi)存空間都初始化為零值(不包括對象頭), 如果使用TLAB,這一工作過程也可以提前至TLAB分配時進行。這一步操作保證了對象的實例字段在Java代碼中可以不賦初始值就直接使用,程序能訪問到這些字段的數(shù)據(jù)類型所對

應的零值。虛擬機是否使用TLAB,可以通過-XX:+/-UseTLAB參數(shù)來設定。

2.應用階段(In Use)

對象至少被一個強引用持有著。

想要了解引用的朋友可以看博文

Java中的四種引用

3.不可見階段(Invisible)

當一個對象處于不可見階段時,說明程序本身不再持有該對象的任何強引用,雖然該這些引用仍然是存在著的。

簡單說就是程序的執(zhí)行已經(jīng)超出了該對象的作用域了。

舉例如下圖:本地變量count在25行時已經(jīng)超出了其作用域,則在此時稱之為count處于不可視階段。當然這種情況編譯器在編譯的過程中會直接報錯了。

4.不可達階段(Unreachable)

對象處于不可達階段是指該對象不再被任何強引用所持有。

與“不可見階段”相比,“不可見階段”是指程序不再持有該對象的任何強引用。對象如果在之前的任何狀態(tài)被JVM等系統(tǒng)下的某些已裝載的靜態(tài)變量或線程或JNI等強引用持有著,這些特殊的強引用被稱為”GC root”。存在著這些GC root會導致對象的內(nèi)存泄露情況,無法被回收,則對方也無法到達“不可達階段”。

5.收集階段(Collected)

當垃圾回收器發(fā)現(xiàn)該對象已經(jīng)處于“不可達階段”并且垃圾回收器已經(jīng)對該對象的內(nèi)存空間重新分配做好準備時,則對象進入了“收集階段”。如果該對象已經(jīng)重寫了finalize()方法,則會去執(zhí)行該方法的終端操作。

這里要特別說明一下:不要重載finazlie()方法!原因有兩點:

l 會影響JVM的對象分配與回收速度

在分配該對象時,JVM需要在垃圾回收器上注冊該對象,以便在回收時能夠執(zhí)行該重載方法;在該方法的執(zhí)行時需要消耗CPU時間且在執(zhí)行完該方法后才會重新執(zhí)行回收操作,即至少需要垃圾回收器對該對象執(zhí)行兩次GC。

l 可能造成該對象的再次“復活”

在finalize()方法中,如果有其它的強引用再次持有該對象,則會導致對象的狀態(tài)由“收集階段”又重新變?yōu)椤皯秒A段”。這個已經(jīng)破壞了Java對象的生命周期進程,且“復活”的對象不利用后續(xù)的代碼管理。

想要了解JVM垃圾回收算法可以點擊鏈接

JVM垃圾回收算法

6.終結階段

當對象執(zhí)行完finalize()方法后仍然處于不可達狀態(tài)時,則該對象進入終結階段。在該階段是等待垃圾回收器對該對象空間進行回收。

7.對象空間重新分配階段

垃圾回收器對該對象的所占用的內(nèi)存空間進行回收或者再分配了,則該對象徹底消失了,稱之為“對象空間重新分配階段”。

總結

以上是生活随笔為你收集整理的java中对象的生存期_Java中对象的生存周期的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。