一.類的加載與檢查
當(dāng)我們new了一個(gè)對(duì)象的時(shí)候,首先會(huì)去檢查一下這個(gè)指令是否在常量池中存在符號(hào)引用,并且檢查這個(gè)符號(hào)引用代表的對(duì)象是否被加載,解析初始化過,如果沒有就要先去進(jìn)行類加載過程
二.分配內(nèi)存
我們通過第一步的檢查后,就會(huì)在堆中劃分出一塊對(duì)象所需要的內(nèi)存大小,至于分配方式有兩種,指針碰撞,空閑列表。選擇哪種分配方式由 Java 堆是否規(guī)整決定,而 Java 堆是否規(guī)整又由所采用的垃圾收集器是否帶有壓縮整理功能決定。
指針碰撞
適用于沒有內(nèi)存碎片的情況,原理:用過的內(nèi)存全部整合到一邊,沒有用過的內(nèi)存放在另一邊,中間有一個(gè)分界指針,只需要向著沒用過的內(nèi)存方向?qū)⒃撝羔樢苿?dòng)對(duì)象內(nèi)存大小位置即可。
使用該分配方式的 GC 收集器:Serial, ParNew
空閑列表
適用于堆內(nèi)存不是很規(guī)則的情況下,原理就是找一塊合適的內(nèi)存來分配給對(duì)象,使用該分配方式的GC收集器 CMS
JAVA內(nèi)存是否規(guī)則取決于垃圾回收器采用的是標(biāo)記-整理法還是標(biāo)記清除法
三.初始化
內(nèi)存分配完成后,虛擬機(jī)需要將分配到的內(nèi)存空間都初始化為零值(不包括對(duì)象頭),這一步操作保證了對(duì)象的實(shí)例字段在 Java 代碼中可以不賦初始值就直接使用,程序能訪問到這些字段的數(shù)據(jù)類型所對(duì)應(yīng)的零值。
四.設(shè)置對(duì)象頭
初始化零值完成之后,虛擬機(jī)要對(duì)對(duì)象進(jìn)行必要的設(shè)置,例如這個(gè)對(duì)象是哪個(gè)類的實(shí)例、如何才能找到類的元數(shù)據(jù)信息、對(duì)象的哈希碼、對(duì)象的 GC 分代年齡等信息。 這些信息存放在對(duì)象頭中。 另外,根據(jù)虛擬機(jī)當(dāng)前運(yùn)行狀態(tài)的不同,如是否啟用偏向鎖等,對(duì)象頭會(huì)有不同的設(shè)置方式。
?
五.執(zhí)行init方法文章來源:http://www.zghlxwxcb.cn/news/detail-738018.html
在上面工作都完成之后,從虛擬機(jī)的視角來看,一個(gè)新的對(duì)象已經(jīng)產(chǎn)生了,但從 Java 程序的視角來看,對(duì)象創(chuàng)建才剛開始,<init> 方法還沒有執(zhí)行,所有的字段都還為零。所以一般來說,執(zhí)行 new 指令之后會(huì)接著執(zhí)行 <init> 方法,把對(duì)象按照程序員的意愿進(jìn)行初始化,這樣一個(gè)真正可用的對(duì)象才算完全產(chǎn)生出來。
?文章來源地址http://www.zghlxwxcb.cn/news/detail-738018.html
到了這里,關(guān)于java對(duì)象的創(chuàng)建過程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!