java中对象的生存期_Java中对象的生存周期
文章目錄
JAVA對(duì)象的生存周期
1.創(chuàng)建階段(Created)
為對(duì)象分配內(nèi)存需要考慮的問(wèn)題
2.應(yīng)用階段(In Use)
3.不可見階段(Invisible)
4.不可達(dá)階段(Unreachable)
5.收集階段(Collected)
6.終結(jié)階段
7.對(duì)象空間重新分配階段
JAVA對(duì)象的生存周期
在Java中,對(duì)象的生命周期包括以下幾個(gè)階段:
創(chuàng)建階段(Created)
應(yīng)用階段(In Use)
不可見階段(Invisible)
不可達(dá)階段(Unreachable)
收集階段(Collected)
終結(jié)階段(Finalized)
對(duì)象空間重分配階段(De-allocated)
1.創(chuàng)建階段(Created)
在創(chuàng)建階段系統(tǒng)通過(guò)下面的幾個(gè)步驟來(lái)完成對(duì)象的創(chuàng)建過(guò)程
虛擬機(jī)遇到new指令,首先去檢查這個(gè)指令的參數(shù)是否能在常量池中定位到一個(gè)類的符號(hào)引用。
檢查符號(hào)引用的類是否引進(jìn)被加載,如果沒有被加載,則執(zhí)行相應(yīng)的類加載過(guò)程。
為對(duì)象分配內(nèi)存(為對(duì)象分配的內(nèi)存大小在類加載時(shí)已經(jīng)確定)(為對(duì)象分配內(nèi)存還有一點(diǎn)知識(shí)點(diǎn)我在后面贅述)
開始構(gòu)造對(duì)象
從超類到子類對(duì)static成員進(jìn)行初始化
超類成員變量按順序初始化,遞歸調(diào)用超類的構(gòu)造方法
子類成員變量按順序初始化,子類構(gòu)造方法調(diào)用
一旦對(duì)象被創(chuàng)建,并被分派給某些變量賦值,這個(gè)對(duì)象的狀態(tài)就切換到了應(yīng)用階段
Java對(duì)象的創(chuàng)建這里涉及到知識(shí)點(diǎn)儲(chǔ)備需要知道,下面這些基本的知識(shí),下面點(diǎn)擊鏈接可以自行查閱。
JVM內(nèi)存區(qū)域劃分
JVM類生命周期概述:加載時(shí)機(jī)與加載過(guò)程
為對(duì)象分配內(nèi)存需要考慮的問(wèn)題
問(wèn)題一:堆內(nèi)存的分配方式
為對(duì)象分配內(nèi)存時(shí),對(duì)象需要的內(nèi)存大小在類加載時(shí)就已經(jīng)確定,這里為對(duì)象分配空間的任務(wù)相當(dāng)于把一塊確定大小的內(nèi)存從堆中劃分出來(lái)。而堆內(nèi)存的分配方式是我們這里要說(shuō)的第一個(gè)問(wèn)題:
分配方式一:指針碰撞
假設(shè)JVM中堆的內(nèi)存是絕對(duì)規(guī)整的,空閑的內(nèi)存在一遍,已經(jīng)被使用的內(nèi)存在一遍,中間由一個(gè)指針進(jìn)行分割。那么對(duì)象的內(nèi)存分配就由將指針移動(dòng)即可。
分配方式二:空閑列表法
如果JVM中堆的內(nèi)存不是規(guī)整的,空閑的內(nèi)存和被使用的內(nèi)存相互交錯(cuò)。這時(shí)虛擬機(jī)需要維護(hù)一個(gè)列表,記錄哪塊內(nèi)存時(shí)空閑的,當(dāng)對(duì)象需要被分配內(nèi)存時(shí),找到一塊足夠大的內(nèi)存分配。
**考慮分配方式取決于JVM堆內(nèi)存是否規(guī)整,而JVM內(nèi)存是否規(guī)整取決于JVM使用的垃圾回收器是否帶有垃圾整理功能。**例如:在使用Serial、ParNew 等帶Compact過(guò)程的收集器時(shí),系統(tǒng)采用的分配算法是指針碰撞;而使用CMS這種基于Mark-Sweep算法的收集器時(shí),通常采用空閑列表。
問(wèn)題二:考慮對(duì)象是否被頻繁創(chuàng)建,線程安全問(wèn)題
即使是修改一個(gè)指正,但是在并發(fā)的情況下也不是安全的。可能存在對(duì)象A正在分配的,可能出現(xiàn)正在給對(duì)象A分配內(nèi)存,指針還沒來(lái)得及修改,對(duì)象B又同時(shí)使用了原來(lái)的指針來(lái)分配內(nèi)存的情況。解決這個(gè)問(wèn)題有兩種方案:
第一種:是對(duì)分配內(nèi)存空間的動(dòng)作進(jìn)行同步處理,實(shí)際上虛擬機(jī)采用CAS配上失敗重試的方式保證更新操作的原子性:
第二種:是把內(nèi)存分配的動(dòng)作按照線程劃分在不同的空間之中進(jìn)行,:即每個(gè)線程在Java堆中預(yù)先分配小塊內(nèi)存,稱為本地線程分配緩沖(Thread Local Allocation Buffer, TLAB)。 哪個(gè)線程要分配內(nèi)存,就在哪個(gè)線程的TLAB上分配,只有TLAB用完并分配新的FLAB時(shí),才需要同步鎖定。虛擬機(jī)是否使用TLAB,可以通過(guò)-XX:+/-UseTLAB參數(shù)來(lái)設(shè)定。
內(nèi)存分配完成后,虛擬機(jī)需要將分配到的內(nèi)存空間都初始化為零值(不包括對(duì)象頭), 如果使用TLAB,這一工作過(guò)程也可以提前至TLAB分配時(shí)進(jìn)行。這一步操作保證了對(duì)象的實(shí)例字段在Java代碼中可以不賦初始值就直接使用,程序能訪問(wèn)到這些字段的數(shù)據(jù)類型所對(duì)
應(yīng)的零值。虛擬機(jī)是否使用TLAB,可以通過(guò)-XX:+/-UseTLAB參數(shù)來(lái)設(shè)定。
2.應(yīng)用階段(In Use)
對(duì)象至少被一個(gè)強(qiáng)引用持有著。
想要了解引用的朋友可以看博文
Java中的四種引用
3.不可見階段(Invisible)
當(dāng)一個(gè)對(duì)象處于不可見階段時(shí),說(shuō)明程序本身不再持有該對(duì)象的任何強(qiáng)引用,雖然該這些引用仍然是存在著的。
簡(jiǎn)單說(shuō)就是程序的執(zhí)行已經(jīng)超出了該對(duì)象的作用域了。
舉例如下圖:本地變量count在25行時(shí)已經(jīng)超出了其作用域,則在此時(shí)稱之為count處于不可視階段。當(dāng)然這種情況編譯器在編譯的過(guò)程中會(huì)直接報(bào)錯(cuò)了。
4.不可達(dá)階段(Unreachable)
對(duì)象處于不可達(dá)階段是指該對(duì)象不再被任何強(qiáng)引用所持有。
與“不可見階段”相比,“不可見階段”是指程序不再持有該對(duì)象的任何強(qiáng)引用。對(duì)象如果在之前的任何狀態(tài)被JVM等系統(tǒng)下的某些已裝載的靜態(tài)變量或線程或JNI等強(qiáng)引用持有著,這些特殊的強(qiáng)引用被稱為”GC root”。存在著這些GC root會(huì)導(dǎo)致對(duì)象的內(nèi)存泄露情況,無(wú)法被回收,則對(duì)方也無(wú)法到達(dá)“不可達(dá)階段”。
5.收集階段(Collected)
當(dāng)垃圾回收器發(fā)現(xiàn)該對(duì)象已經(jīng)處于“不可達(dá)階段”并且垃圾回收器已經(jīng)對(duì)該對(duì)象的內(nèi)存空間重新分配做好準(zhǔn)備時(shí),則對(duì)象進(jìn)入了“收集階段”。如果該對(duì)象已經(jīng)重寫了finalize()方法,則會(huì)去執(zhí)行該方法的終端操作。
這里要特別說(shuō)明一下:不要重載finazlie()方法!原因有兩點(diǎn):
l 會(huì)影響JVM的對(duì)象分配與回收速度
在分配該對(duì)象時(shí),JVM需要在垃圾回收器上注冊(cè)該對(duì)象,以便在回收時(shí)能夠執(zhí)行該重載方法;在該方法的執(zhí)行時(shí)需要消耗CPU時(shí)間且在執(zhí)行完該方法后才會(huì)重新執(zhí)行回收操作,即至少需要垃圾回收器對(duì)該對(duì)象執(zhí)行兩次GC。
l 可能造成該對(duì)象的再次“復(fù)活”
在finalize()方法中,如果有其它的強(qiáng)引用再次持有該對(duì)象,則會(huì)導(dǎo)致對(duì)象的狀態(tài)由“收集階段”又重新變?yōu)椤皯?yīng)用階段”。這個(gè)已經(jīng)破壞了Java對(duì)象的生命周期進(jìn)程,且“復(fù)活”的對(duì)象不利用后續(xù)的代碼管理。
想要了解JVM垃圾回收算法可以點(diǎn)擊鏈接
JVM垃圾回收算法
6.終結(jié)階段
當(dāng)對(duì)象執(zhí)行完finalize()方法后仍然處于不可達(dá)狀態(tài)時(shí),則該對(duì)象進(jìn)入終結(jié)階段。在該階段是等待垃圾回收器對(duì)該對(duì)象空間進(jìn)行回收。
7.對(duì)象空間重新分配階段
垃圾回收器對(duì)該對(duì)象的所占用的內(nèi)存空間進(jìn)行回收或者再分配了,則該對(duì)象徹底消失了,稱之為“對(duì)象空間重新分配階段”。
總結(jié)
以上是生活随笔為你收集整理的java中对象的生存期_Java中对象的生存周期的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 百一测评java基础答案_百一测评——《
- 下一篇: java环境变量path好长_java环