欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中對(duì)象的創(chuàng)建和銷(xiāo)毀過(guò)程詳析

 更新時(shí)間:2025年02月24日 11:03:34   作者:顏淡慕瀟  
這篇文章主要介紹了Java中對(duì)象的創(chuàng)建和銷(xiāo)毀過(guò)程,對(duì)象的創(chuàng)建過(guò)程包括類(lèi)加載檢查、內(nèi)存分配、初始化零值內(nèi)存、設(shè)置對(duì)象頭和執(zhí)行init方法,對(duì)象的銷(xiāo)毀過(guò)程由垃圾回收機(jī)制負(fù)責(zé),文中介紹的非常詳細(xì),需要的朋友可以參考下

前言

在 Java 編程里,對(duì)象的創(chuàng)建和銷(xiāo)毀是基礎(chǔ)且關(guān)鍵的操作,深刻理解這一過(guò)程有助于編寫(xiě)出高效、穩(wěn)定的代碼。下面將詳細(xì)闡述 Java 中對(duì)象的創(chuàng)建和銷(xiāo)毀過(guò)程。

對(duì)象的創(chuàng)建過(guò)程

1. 類(lèi)加載檢查

當(dāng)代碼中使用 new 關(guān)鍵字創(chuàng)建對(duì)象時(shí),Java 虛擬機(jī)(JVM)首先會(huì)檢查該對(duì)象對(duì)應(yīng)的類(lèi)是否已經(jīng)被加載到內(nèi)存中。如果尚未加載,JVM 會(huì)通過(guò)類(lèi)加載器將該類(lèi)的字節(jié)碼文件加載到內(nèi)存,并對(duì)其進(jìn)行驗(yàn)證、準(zhǔn)備和解析等操作,最終完成類(lèi)的初始化。例如,當(dāng)執(zhí)行 Person person = new Person(); 時(shí),JVM 會(huì)先確認(rèn) Person 類(lèi)是否已加載。

2. 分配內(nèi)存

類(lèi)加載完成后,JVM 會(huì)為新對(duì)象分配內(nèi)存空間。分配內(nèi)存的方式主要有兩種:

  • 指針碰撞:假設(shè) Java 堆中的內(nèi)存是規(guī)整的,所有用過(guò)的內(nèi)存放在一邊,空閑的內(nèi)存放在另一邊,中間放著一個(gè)指針作為分界點(diǎn)的指示器,那所分配內(nèi)存就僅僅是把那個(gè)指針向空閑空間那邊挪動(dòng)一段與對(duì)象大小相等的距離,這種分配方式稱(chēng)為“指針碰撞”(Bump the Pointer)。
  • 空閑列表:如果 Java 堆中的內(nèi)存并不是規(guī)整的,已使用的內(nèi)存和空閑的內(nèi)存相互交錯(cuò),那就沒(méi)有辦法簡(jiǎn)單地進(jìn)行指針碰撞了,虛擬機(jī)就必須維護(hù)一個(gè)列表,記錄上哪些內(nèi)存塊是可用的,在分配的時(shí)候從列表中找到一塊足夠大的空間劃分給對(duì)象實(shí)例,并更新列表上的記錄,這種分配方式稱(chēng)為“空閑列表”(Free List)。

選擇哪種分配方式由 Java 堆是否規(guī)整決定,而 Java 堆是否規(guī)整又由所采用的垃圾收集器是否帶有空間壓縮整理(Compact)的能力決定。

3. 初始化零值

內(nèi)存分配完成后,JVM 會(huì)將分配到的內(nèi)存空間都初始化為零值(不包括對(duì)象頭)。這一步操作保證了對(duì)象的實(shí)例字段在 Java 代碼中可以不賦初始值就直接使用,程序能訪問(wèn)到這些字段的數(shù)據(jù)類(lèi)型所對(duì)應(yīng)的零值。例如,int 類(lèi)型的字段初始值為 0,boolean 類(lèi)型的字段初始值為 false。

4. 設(shè)置對(duì)象頭

JVM 會(huì)對(duì)對(duì)象進(jìn)行必要的設(shè)置,例如這個(gè)對(duì)象是哪個(gè)類(lèi)的實(shí)例、如何才能找到類(lèi)的元數(shù)據(jù)信息、對(duì)象的哈希碼、對(duì)象的 GC 分代年齡等信息。這些信息存放在對(duì)象的對(duì)象頭(Object Header)之中。

5. 執(zhí)行 init 方法

在上述工作都完成之后,從 Java 程序的視角看來(lái),對(duì)象已經(jīng)產(chǎn)生了,但從 JVM 的視角來(lái)看,對(duì)象創(chuàng)建才剛剛開(kāi)始——<init> 方法還沒(méi)有執(zhí)行,所有的字段都還為零。所以一般來(lái)說(shuō)(由字節(jié)碼中是否跟隨有 invokespecial 指令所決定),執(zhí)行 new 指令之后會(huì)接著執(zhí)行 <init> 方法,把對(duì)象按照程序員的意愿進(jìn)行初始化,這樣一個(gè)真正可用的對(duì)象才算完全被構(gòu)造出來(lái)。

對(duì)象的銷(xiāo)毀過(guò)程

1. 可達(dá)性分析

在 Java 中,對(duì)象的銷(xiāo)毀主要由垃圾回收機(jī)制(GC)負(fù)責(zé)。JVM 會(huì)通過(guò)可達(dá)性分析算法來(lái)判斷對(duì)象是否存活。該算法以一系列被稱(chēng)為“GC Roots”的對(duì)象為起始點(diǎn),從這些節(jié)點(diǎn)開(kāi)始向下搜索,搜索所走過(guò)的路徑稱(chēng)為引用鏈,當(dāng)一個(gè)對(duì)象到 GC Roots 沒(méi)有任何引用鏈相連時(shí),則證明此對(duì)象是不可達(dá)的,就有可能被回收。常見(jiàn)的 GC Roots 包括:

  • 虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象。
  • 方法區(qū)中類(lèi)靜態(tài)屬性引用的對(duì)象。
  • 方法區(qū)中常量引用的對(duì)象。
  • 本地方法棧中 JNI(即一般說(shuō)的 Native 方法)引用的對(duì)象。

2. 第一次標(biāo)記

當(dāng)對(duì)象被判定為不可達(dá)時(shí),它會(huì)被第一次標(biāo)記。但此時(shí)對(duì)象還不會(huì)被立即回收,而是會(huì)被放入一個(gè)名為 F - Queue 的隊(duì)列中,并由一個(gè)低優(yōu)先級(jí)的線程去執(zhí)行隊(duì)列中對(duì)象的 finalize() 方法(如果對(duì)象重寫(xiě)了該方法)。

3. finalize() 方法執(zhí)行

finalize() 方法是對(duì)象逃脫死亡命運(yùn)的最后一次機(jī)會(huì)。在該方法中,對(duì)象可以重新與引用鏈上的任何一個(gè)對(duì)象建立關(guān)聯(lián),例如把自己(this 關(guān)鍵字)賦值給某個(gè)類(lèi)變量或者對(duì)象的成員變量。如果對(duì)象在 finalize() 方法中成功拯救了自己,那在第二次標(biāo)記時(shí)它將被移除出“即將回收”的集合;如果對(duì)象沒(méi)有逃脫,那基本上它就真的要被回收了。不過(guò)需要注意的是,finalize() 方法的執(zhí)行是不可靠的,JVM 并不保證該方法一定會(huì)被執(zhí)行。

4. 第二次標(biāo)記

如果對(duì)象在 finalize() 方法執(zhí)行后仍然沒(méi)有與 GC Roots 建立引用關(guān)系,它會(huì)被進(jìn)行第二次標(biāo)記。經(jīng)過(guò)第二次標(biāo)記的對(duì)象,就會(huì)被真正地列入可回收對(duì)象的集合。

5. 垃圾回收

當(dāng)垃圾回收器執(zhí)行垃圾回收操作時(shí),會(huì)回收那些經(jīng)過(guò)第二次標(biāo)記的對(duì)象所占用的內(nèi)存空間,將其釋放回 Java 堆中,供后續(xù)新對(duì)象的分配使用。不同的垃圾回收器采用不同的算法和策略來(lái)執(zhí)行垃圾回收,例如標(biāo)記 - 清除算法、標(biāo)記 - 整理算法、復(fù)制算法等。

知識(shí)補(bǔ)充:

在 Java 虛擬機(jī)的堆區(qū),每個(gè)對(duì)象都可能處于以下三種狀態(tài)之一。

1)可觸及狀態(tài):當(dāng)一個(gè)對(duì)象被創(chuàng)建后,只要程序中還有引用變量引用它,那么它就始終處于可觸及狀態(tài)。

2)可復(fù)活狀態(tài):當(dāng)程序不再有任何引用變量引用該對(duì)象時(shí),該對(duì)象就進(jìn)入可復(fù)活狀態(tài)。在這個(gè)狀態(tài)下,垃圾回收器會(huì)準(zhǔn)備釋放它所占用的內(nèi)存,在釋放之前,會(huì)調(diào)用它及其他處于可復(fù)活狀態(tài)的對(duì)象的 finalize() 方法,這些 finalize() 方法有可能使該對(duì)象重新轉(zhuǎn)到可觸及狀態(tài)。

3)不可觸及狀態(tài):當(dāng) Java 虛擬機(jī)執(zhí)行完所有可復(fù)活對(duì)象的 finalize() 方法后,如果這些方法都沒(méi)有使該對(duì)象轉(zhuǎn)到可觸及狀態(tài),垃圾回收器才會(huì)真正回收它占用的內(nèi)存。

總結(jié)

到此這篇關(guān)于Java中對(duì)象的創(chuàng)建和銷(xiāo)毀過(guò)程的文章就介紹到這了,更多相關(guān)Java對(duì)象的創(chuàng)建和銷(xiāo)毀內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring?Boot?整合持久層之Spring Data JPA

    Spring?Boot?整合持久層之Spring Data JPA

    在介紹Spring Data JPA的時(shí)候,我們首先認(rèn)識(shí)下Hibernate。Hibernate是數(shù)據(jù)訪問(wèn)解決技術(shù)的絕對(duì)霸主,使用O/R映射技術(shù)實(shí)現(xiàn)數(shù)據(jù)訪問(wèn),O/R映射即將領(lǐng)域模型類(lèi)和數(shù)據(jù)庫(kù)的表進(jìn)行映射,通過(guò)程序操作對(duì)象而實(shí)現(xiàn)表數(shù)據(jù)操作的能力,讓數(shù)據(jù)訪問(wèn)操作無(wú)須關(guān)注數(shù)據(jù)庫(kù)相關(guān)的技術(shù)
    2022-08-08
  • @RefreshScope(nacos配置熱更新方式)

    @RefreshScope(nacos配置熱更新方式)

    文章主要介紹了Spring和Nacos對(duì)`@RefreshScope`注解的處理方式,Spring在每次調(diào)用被`@RefreshScope`注解的bean的屬性時(shí),會(huì)先從本地緩存獲取,如果緩存不存在則重新創(chuàng)建并獲取最新環(huán)境配置
    2024-12-12
  • java中Ajax與Axios的使用小結(jié)

    java中Ajax與Axios的使用小結(jié)

    在項(xiàng)目中我們經(jīng)常會(huì)遇到需要向請(qǐng)求頭中添加消息的場(chǎng)景,本文主要介紹了java中Ajax與Axios的使用小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • 解決Javaweb 提交表單到servlet時(shí)出現(xiàn)空白頁(yè)面,但網(wǎng)站不報(bào)錯(cuò)問(wèn)題

    解決Javaweb 提交表單到servlet時(shí)出現(xiàn)空白頁(yè)面,但網(wǎng)站不報(bào)錯(cuò)問(wèn)題

    這篇文章主要介紹了解決Javaweb 提交表單到servlet時(shí)出現(xiàn)空白頁(yè)面,但網(wǎng)站不報(bào)錯(cuò)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • springboot+angular4前后端分離 跨域問(wèn)題解決詳解

    springboot+angular4前后端分離 跨域問(wèn)題解決詳解

    這篇文章主要介紹了springboot+angular4前后端分離 跨域問(wèn)題解決詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Java線程休眠的5種方法

    Java線程休眠的5種方法

    這篇文章主要介紹了Java線程休眠的5種方法,分別是Thread.sleep、TimeUnit、wait、Condition、LockSupport,下面文章將對(duì)這五種方法進(jìn)行詳細(xì)講解,需要的小伙伴可以參考一下
    2022-05-05
  • Spring的IOC控制反轉(zhuǎn)詳解

    Spring的IOC控制反轉(zhuǎn)詳解

    這篇文章主要為大家介紹了Spring的IOC控制反轉(zhuǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助<BR>
    2022-01-01
  • SpringBoot替換默認(rèn)的tomcat服務(wù)器的方法

    SpringBoot替換默認(rèn)的tomcat服務(wù)器的方法

    Tomcat是Apache基金下的一個(gè)輕量級(jí)的Servlet容器,支持Servlet和JSP,Tomcat具有Web服務(wù)器特有的功能,在SpringBoot框架中,我們使用最多的是Tomcat,這是SpringBoot默認(rèn)的容器技術(shù),本文給大家介紹了Spring?Boot如何替換默認(rèn)的tomcat服務(wù)器,需要的朋友可以參考下
    2024-08-08
  • springboot自定義starter方法及注解實(shí)例

    springboot自定義starter方法及注解實(shí)例

    這篇文章主要為大家介紹了springboot自定義starter方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • SpringBoot 動(dòng)態(tài)配置Profile環(huán)境的方式

    SpringBoot 動(dòng)態(tài)配置Profile環(huán)境的方式

    這篇文章主要介紹了SpringBoot 動(dòng)態(tài)配置Profile環(huán)境的方式,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-10-10

最新評(píng)論