国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程

這篇具有很好參考價值的文章主要介紹了【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

一、java創(chuàng)建對象的幾種方式

1.1、使用new關(guān)鍵字

?1.2、反射創(chuàng)建對象

1.2.1、Class.newInstance創(chuàng)建對象

1.2.2、調(diào)用構(gòu)造器再去創(chuàng)建對象Constructor.newInstance

?1.3、clone實現(xiàn)

1.4、反序列化

二、創(chuàng)建對象的過程

2.1、分配空間的方式

1、指針碰撞

2、空閑列表

3、怎么選擇分配方式

三、注意事項


一、java創(chuàng)建對象的幾種方式

1.1、使用new關(guān)鍵字

調(diào)用類的構(gòu)造方法創(chuàng)建對象

【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程,jvm,java,開發(fā)語言

?1.2、反射創(chuàng)建對象

1.2.1、Class.newInstance創(chuàng)建對象

【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程,jvm,java,開發(fā)語言

1.2.2、調(diào)用構(gòu)造器再去創(chuàng)建對象Constructor.newInstance

先通過反射獲取類中無參構(gòu)造器,然后通過newInstance()獲取對象

【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程,jvm,java,開發(fā)語言

?1.3、clone實現(xiàn)

通過Clone創(chuàng)建對象,首先實體類中必須先實現(xiàn)Cloneable接口并復(fù)寫Object的clone方法(因為Object的這個方法是protected的)

【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程,jvm,java,開發(fā)語言

?【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程,jvm,java,開發(fā)語言

1.4、反序列化

序列化:指把 Java 對象轉(zhuǎn)換為字節(jié)序列的過程;
反序列化:指把字節(jié)序列恢復(fù)為 Java 對象的過程;
此方式需要類先實現(xiàn)Serializable接口

【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程,jvm,java,開發(fā)語言

public class TestStack {
    public static void main(String[] args) throws Exception {
        File file =new File("M:/Serializable.txt");
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);
        UserParam userParam =new UserParam("hello");
        outputStream.writeObject(userParam);
        FileInputStream fileInputStream  = new FileInputStream(file);
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        UserParam userParam1 = (UserParam)objectInputStream.readObject();
        userParam1.setNickName("world");
        System.out.println(userParam1);
    }
}

二、創(chuàng)建對象的過程

當(dāng)Java虛擬機遇到一條字節(jié)碼new指令時:

1、檢查類是否已經(jīng)被加載

????????去常量池中查找該引用所指向的類有沒有被虛擬機加載,如果沒有被加載,那么會進行類的加載過程。類的加載過程需要經(jīng)歷:加載、鏈接、初始化三個階段。對象的大小,在類加載完成時確定。(jdk1.8中,運行時常量池、類常量池存在于方法區(qū)中。)

2、 為對象分配內(nèi)存空間

????????JVM為對象分配空間,即把一塊確定大小的內(nèi)存塊從Java堆中劃分出來。

2.1、分配空間的方式

1、指針碰撞

????????假設(shè)Java堆中內(nèi)存是絕對規(guī)整的,所有被使用過的內(nèi)存都被放在一邊,空閑的內(nèi)存被放在另一邊,中間放著一個指針作為分界點的指示器,那所分配內(nèi)存就僅僅是把那個指針向空閑空間方向挪動一段與對象大小相等的距離。

①正常情況

【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程,jvm,java,開發(fā)語言

②給對象分配內(nèi)存后

【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程,jvm,java,開發(fā)語言

?

這種方式的優(yōu)點是工作簡單,效率高,只需要移動指針就可以分配內(nèi)存空間。

缺點也很明顯:由于用指針碰撞分配內(nèi)存空間分為兩步:

1、讀取指針當(dāng)前的位置。

2、根據(jù)自身大小移動指針,不是原子操作,對象創(chuàng)建在虛擬機中是非常頻繁的操作,在并發(fā)情況下,會導(dǎo)致執(zhí)行讀操作或執(zhí)行寫操作的結(jié)果與預(yù)設(shè)的結(jié)果不一致(指針劃分不一致)。

????????例如:線程A要給對象分配8kb,讀取到指針當(dāng)前的位置,時間片用完,切換到線程B,線程B要給它的對象分配16kb,也讀取到指針當(dāng)前的位置(和線程A讀取到的一樣),將指針向空閑內(nèi)存方向移動16kb大小,線程B時間片用完,切換到線程A繼續(xù)執(zhí)行,由于線程A使用的指針位置還是之前讀到的。(線程不安全問題)

③針對指針碰撞線程不安全,有兩種方案:

1、同步處理(加鎖)分配內(nèi)存空間行為

采用 CAS 分配重試的方式來保證更新操作的原子性

2、把內(nèi)存分配行為按照線程,劃分在不同的內(nèi)存空間進行

1、即每個線程在Java堆中預(yù)先分配一小塊內(nèi)存,稱為本地線程分配緩沖(Thread Local Allocation Buffer,TLAB),哪個線程要分配內(nèi)存,就在哪個線程的本地緩沖區(qū)中分配,只有本地緩沖區(qū)用完了,分配新的緩存區(qū)時才需要同步鎖定
2、虛擬機是否使用TLAB,可以通過-XX:+/-UseTLAB參數(shù)來設(shè)定。

2、空閑列表

????????如果Java堆中的內(nèi)存并不是規(guī)整的,?已被使用的內(nèi)存和空閑的內(nèi)存相互交錯在一起,那就沒有辦法簡單地進行指針碰撞了,虛擬機就必須維護一個列表,記錄上哪些內(nèi)存塊是可用的,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,并更新列表上的記錄。

3、怎么選擇分配方式

????????兩種方式的選擇由 Java 堆是否規(guī)整決定,Java 堆是否規(guī)整是由選擇的垃圾收集器是否具有壓縮整理能力決定的。

①將內(nèi)存空間初始化為零值
????????內(nèi)存分配完成之后,虛擬機必須將分配到的內(nèi)存空間(但不包括對象頭)都初始化為零值。零值初始化意思就是對對象的字段賦0值,或者null值,這也就解釋了為什么這些字段在不需要進程初始化時候就能直接使用。
????????如果使用了TLAB的話,這一項工作也可以提前至TLAB分配時順便進行。

②對對象進行必要的設(shè)置
????????例如這個對象是哪個類的實例、如何才能找到類的元數(shù)據(jù)信息、對象的哈希碼、對象的GC分代年齡等信息。這些信息存放在對象的對象頭中。

????????從虛擬機的視角來看,一個新的對象已經(jīng)產(chǎn)生了。但是從Java程序的視角看來,對象創(chuàng)建才剛剛開始——構(gòu)造函數(shù),即Class文件中的()方法還沒有執(zhí)行,所有的字段都為默認(rèn)的零值,對象需要的其他資源和狀態(tài)信息也還沒有按照預(yù)定的意圖構(gòu)造好。

③執(zhí)行實例的初始化方法init

????????init方法包含成員變量、構(gòu)造代碼塊的初始化,按照聲明的順序執(zhí)行,執(zhí)行對象的構(gòu)造
方法,并把堆內(nèi)對象的首地址賦值給引用變量。至此,對象創(chuàng)建成功。

【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程,jvm,java,開發(fā)語言

三、注意事項

????????并發(fā)情況下,需要考慮操作的步驟是不是原子性,如果不是,就要加鎖。原子性就是動作不能再繼續(xù)被拆分了,讀是原子性,寫也是原子性,但是讀加上寫就不是原子性。文章來源地址http://www.zghlxwxcb.cn/news/detail-614044.html

到了這里,關(guān)于【JVM】詳細(xì)解析java創(chuàng)建對象的具體流程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Java進階(1)——JVM的內(nèi)存分配 & 反射Class類的類對象 & 創(chuàng)建對象的幾種方式 & 類加載(何時進入內(nèi)存JVM)& 注解 & 反射+注解的案例

    Java進階(1)——JVM的內(nèi)存分配 & 反射Class類的類對象 & 創(chuàng)建對象的幾種方式 & 類加載(何時進入內(nèi)存JVM)& 注解 & 反射+注解的案例

    1.java運行時的內(nèi)存分配,創(chuàng)建對象時內(nèi)存分配; 2.類加載的順序,創(chuàng)建一個唯一的類的類對象; 3.創(chuàng)建對象的方式,new,Class.forName,clone; 4.什么時候加載.class文件進入JVM內(nèi)存中,看到new,Class.forName; 5.如何加載?雙親委托(委派)機制:安全;AppClassLoader; 6.反射實質(zhì):能

    2024年02月14日
    瀏覽(32)
  • Jvm創(chuàng)建對象之內(nèi)存分配-JVM(七)

    Jvm創(chuàng)建對象之內(nèi)存分配-JVM(七)

    上篇文章介紹了jvm創(chuàng)建,會校驗是否已加載類,沒有則加載,通過之前學(xué)的源碼,classLoader加載完之后,虛擬機開始給類分配內(nèi)存,指針移動分配和free鏈表分配,解決并發(fā)分配情況用cap和TLAB方法。之后設(shè)置對象頭部信息,有mark word線程鎖,分代年齡等,klass pointer。還有指針

    2024年02月13日
    瀏覽(25)
  • JVM中對象創(chuàng)建過程

    JVM中對象創(chuàng)建過程

    在JVM中對象的創(chuàng)建,我們從一個new指令開始: 這個過程大概圖示如下: 虛擬機收到new指令觸發(fā)。 類加載檢查:如果類沒有被類加載器加載,則執(zhí)行類加載流程(將class信息加載到JVM的運行時數(shù)據(jù)區(qū)的過程),對象所需內(nèi)存大小在類加載完后可以完全確定。 對象分配內(nèi)存:從

    2024年03月22日
    瀏覽(26)
  • 04-JVM對象創(chuàng)建深度剖析

    04-JVM對象創(chuàng)建深度剖析

    上一篇:03-JVM內(nèi)存模型剖析與優(yōu)化 對象創(chuàng)建的主要流程: 虛擬機遇到一條new指令時,首先將去檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號引用,并且檢查這個符號引用代表的類是否已被加載、解析和初始化過。如果沒有,那必須先執(zhí)行相應(yīng)的類加載過程。 ne

    2024年02月09日
    瀏覽(22)
  • jvm對象創(chuàng)建和內(nèi)存分配優(yōu)化

    jvm對象創(chuàng)建和內(nèi)存分配優(yōu)化

    1、類加載檢測 虛擬機遇到一條new指令時,首先將去檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號引用,并且檢查這個符號引用代表的類是否是否已被加載、解析和初始化過。如果沒有,那必須先執(zhí)行相應(yīng)的類加載過程。 new指令對應(yīng)語言層面講是,new、對

    2024年02月13日
    瀏覽(33)
  • JVM面試題-JVM對象的創(chuàng)建過程、內(nèi)存分配、內(nèi)存布局、訪問定位等問題詳解

    JVM面試題-JVM對象的創(chuàng)建過程、內(nèi)存分配、內(nèi)存布局、訪問定位等問題詳解

    內(nèi)存分配的兩種方式 指針碰撞 適用場合:堆內(nèi)存 規(guī)整 (即沒有內(nèi)存碎片)的情況下。 原理:用過的內(nèi)存全部整合到一邊,沒有用過的內(nèi)存放在另一邊,中間有一個分界指針,只需要向著沒用過的內(nèi)存方向?qū)⒃撝羔樢苿訉ο髢?nèi)存大小位置即可。 使用該分配方式的GC收集器:

    2024年02月08日
    瀏覽(19)
  • JVM運行時區(qū)域——對象創(chuàng)建內(nèi)存分配過程

    JVM運行時區(qū)域——對象創(chuàng)建內(nèi)存分配過程

    ????????新創(chuàng)建的對象 , 都存放在伊甸園區(qū)域 ,當(dāng)垃圾回收時,將伊甸園區(qū)域的垃圾數(shù)據(jù)銷毀,然后將存活的對象轉(zhuǎn)移到幸存者0區(qū)域,之后創(chuàng)建的新的對象還是存放在伊甸園區(qū)域,等到再次垃圾回收后,將伊甸園區(qū)域和幸存者0區(qū)域中存活的對象一起轉(zhuǎn)移到幸存者1區(qū)域中

    2024年02月15日
    瀏覽(22)
  • JVM對象創(chuàng)建與內(nèi)存分配機制深度剖析

    JVM對象創(chuàng)建與內(nèi)存分配機制深度剖析

    (1)類加載檢查 虛擬機遇到一條new指令時,首先將去檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號引用,并且檢查這個符號引用代表的類是否已被加載、解析和初始化過。如果沒有,那必須先執(zhí)行相應(yīng)的類加載過程; 所以所類加載是 懶加載 ; new指令對應(yīng)到語

    2024年02月13日
    瀏覽(26)
  • Java進階(4)——結(jié)合類加載JVM的過程理解創(chuàng)建對象的幾種方式:new,反射Class,克隆clone(拷貝),序列化反序列化

    Java進階(4)——結(jié)合類加載JVM的過程理解創(chuàng)建對象的幾種方式:new,反射Class,克隆clone(拷貝),序列化反序列化

    1.類什么時候被加載到JVM中,new,Class.forName: Class.forName(“包名.類名”); 2.創(chuàng)建對象的方式,反射,本質(zhì)是獲得類的類對象Class; 3.克隆clone,深拷貝,淺拷貝的對比; 4.序列化和反序列化的方式; Hello h; // 此時沒有用Hello,jvm并沒有進行類加載 看到new : new Book() Class.forName:

    2024年02月12日
    瀏覽(30)
  • JVM 創(chuàng)建對象時分配內(nèi)存的幾種方法、分配方法的選擇

    ????????假設(shè)Java堆中內(nèi)存是絕對規(guī)整的,所有被使用過的內(nèi)存都被放在一邊,空閑的內(nèi)存被放在另一邊,中間放著一個指針作為分界點的指示器,那所分配內(nèi)存就僅僅是把那 個指針向空閑空間方向挪動一段與對象大小相等的距離。 ????????如果Java堆中的內(nèi)存并不是規(guī)

    2024年02月10日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包