溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

當(dāng)Jvm遇到new關(guān)鍵字會(huì)發(fā)生什么

發(fā)布時(shí)間:2021-07-13 09:05:54 來(lái)源:億速云 閱讀:139 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要介紹“當(dāng)Jvm遇到new關(guān)鍵字會(huì)發(fā)生什么”,在日常操作中,相信很多人在當(dāng)Jvm遇到new關(guān)鍵字會(huì)發(fā)生什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”當(dāng)Jvm遇到new關(guān)鍵字會(huì)發(fā)生什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

在上一篇我們知道了Jvm的內(nèi)存劃分,這一篇我們來(lái)具體分析一下,當(dāng)我們用new關(guān)鍵字創(chuàng)建一個(gè)新對(duì)象時(shí),Jvm都做了哪些工作。當(dāng)虛擬機(jī)執(zhí)行到new指令時(shí),發(fā)現(xiàn)它是關(guān)鍵字,于是會(huì)檢查這個(gè)指令參數(shù)是否能在常量池中找到相關(guān)的引用,并檢查這個(gè)引用所代表的類是否被加載、解析和初始化過(guò)。如果沒(méi)有被加載,則先執(zhí)行類的加載過(guò)程。當(dāng)類加載成功后,虛擬機(jī)就會(huì)為新創(chuàng)建的對(duì)象分配內(nèi)存。分配內(nèi)存無(wú)非就是在Java堆上劃出一部分區(qū)域來(lái)作為新對(duì)象的存儲(chǔ)空間。但在實(shí)際的處理時(shí)是比較麻煩的。例如怎么找到空閑的內(nèi)存,如何劃分固定大小內(nèi)存。我們知道Java虛擬機(jī)規(guī)范中所說(shuō)虛擬機(jī)中的堆內(nèi)存可以是連續(xù)的也可以是不連續(xù)的。所以虛擬機(jī)在為對(duì)象分配新內(nèi)存時(shí),就要根據(jù)這兩種不同的方式來(lái)采取不同的實(shí)現(xiàn)。這兩種方式分別叫作:指針碰撞和空閑列表。正面我們分別看一下它們具體的實(shí)現(xiàn)方式。

  • 指針碰撞:所謂的連續(xù)內(nèi)存是指Java堆中的內(nèi)存是絕對(duì)規(guī)整的,用過(guò)的內(nèi)存在一邊,空閑的內(nèi)存在另一邊。中間有個(gè)指針作為分界點(diǎn),這時(shí)如果要分配新內(nèi)存,只要指針向空閑的內(nèi)存一方移動(dòng)一下就可以了。這種分配內(nèi)存的方式就叫指針碰撞。

  • 空閑列表:如果Java堆中的內(nèi)存并不是完整的,也就是不是連續(xù)的。這時(shí)使用的內(nèi)存和空閑的內(nèi)存沒(méi)有任何規(guī)則,無(wú)法用指針碰撞的方式,來(lái)分配內(nèi)存。這時(shí)虛擬機(jī)只能采取其它辦法來(lái)標(biāo)識(shí)出哪些內(nèi)存是使用的,哪些內(nèi)存是空閑的,所以虛擬機(jī)就要維護(hù)一個(gè)列表,用來(lái)存儲(chǔ)哪些內(nèi)存是空閑的,分配內(nèi)存時(shí),只要從列表中劃分一塊區(qū)域存儲(chǔ)對(duì)象實(shí)例,并更新列表上的記錄就可以了。這種方式就叫空閑列表。

由于不同的虛擬機(jī)所采用的內(nèi)存分配方式是不同的,所以上述主要說(shuō)明兩種分配內(nèi)存的方式,虛擬機(jī)到底采用哪種方式由不同虛擬機(jī)的堆自行決定。

上述的過(guò)程只是給對(duì)象分配了相關(guān)的內(nèi)存空間,但對(duì)象還是空的,內(nèi)存數(shù)據(jù)要怎么保存對(duì)象的信息呢?在虛擬機(jī)中對(duì)象在內(nèi)存中存儲(chǔ)主要分3個(gè)區(qū)域:

  • 對(duì)象頭:主要包括兩部分一個(gè)是對(duì)象自己的運(yùn)行數(shù)據(jù)如哈希碼、GC分代年齡、鎖狀態(tài)標(biāo)識(shí)、線程持有的鎖、偏向線程ID等官方稱知為Mark Word。對(duì)象頭的另一部分就是類型指針,也就是對(duì)象指向類元數(shù)據(jù)的指針,虛擬機(jī)通過(guò)這個(gè)指針確定這個(gè)對(duì)象是哪個(gè)類的實(shí)例。對(duì)象頭的信息是不固定的,如果對(duì)象是一個(gè)數(shù)組,那么在對(duì)象頭中就會(huì)有記錄數(shù)組長(zhǎng)度的信息。

當(dāng)Jvm遇到new關(guān)鍵字會(huì)發(fā)生什么

  • 實(shí)例數(shù)據(jù):也就是程序中自定義的各種字段的類型和內(nèi)容,包括父類或子類的數(shù)據(jù)都在這里保存,這是對(duì)象真正的存儲(chǔ)的有效信息。

  • 對(duì)齊填充:主要的作是就是占位符。因?yàn)樘摂M機(jī)要求對(duì)象起始地址必須是8字節(jié)的整數(shù)倍也就是對(duì)象大小必須是8的整數(shù)倍,因此,如果對(duì)象的實(shí)例數(shù)據(jù)沒(méi)有對(duì)齊時(shí),就會(huì)需要通過(guò)對(duì)齊填充來(lái)補(bǔ)齊。

對(duì)象現(xiàn)在已經(jīng)創(chuàng)建完了,但它是存儲(chǔ)在堆上的,為了方便我們操作堆中的對(duì)象,Java是通過(guò)棧上的引用數(shù)據(jù)來(lái)操作堆上的具體對(duì)象的。這個(gè)引用是使用直接指針訪問(wèn)的。堆中要存儲(chǔ)這個(gè)指針的相關(guān)信息,而引用存儲(chǔ)的就是該對(duì)象的內(nèi)存地址。

當(dāng)Jvm遇到new關(guān)鍵字會(huì)發(fā)生什么

到此,關(guān)于“當(dāng)Jvm遇到new關(guān)鍵字會(huì)發(fā)生什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

jvm
AI