真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

【Java語言】對象的創(chuàng)建過程詳細說明-創(chuàng)新互聯(lián)

  1. 當(dāng)Java虛擬機遇到一條字節(jié)碼new指令時,首先會去檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號引用,并且檢查這個符號引用代表的類是否已經(jīng)被加載、解析和初始化過。如果沒有,那必須先執(zhí)行相應(yīng)的類加載過程。
  2. 在類加載檢查通過后,接下來虛擬機將為新生對象分配內(nèi)存。對象所需內(nèi)存的大小在類加載完成后便可完全確定,為對象分配空間的任務(wù)實際上便等同于把一塊確定大小的內(nèi)存塊從Java堆中劃分出來。
  3. 內(nèi)存分配完成后,虛擬機必須將分配到的內(nèi)存空間(不包含對象頭)都初始化為零值(如果使用了TLAB的話,這一項工作也可以提前至TLAB分配時順便進行TLAB為本地線程分配緩沖 詳解可見下文)。這步操作保證了對象的實例字段在Java代碼中可以不賦初始值就直接使用,使程序能訪問到這些字段的數(shù)據(jù)類型所對應(yīng)的零值。
  4. 接下來,Java虛擬機還要對對象進行必要的設(shè)置,例如這個對象是哪個類的實例、如何才能找到類的元數(shù)據(jù)信息、對象的哈希碼、對象的GC分代年齡等信息。這些信息保存在對象的對象頭中。根據(jù)虛擬機當(dāng)前運行狀態(tài)的不同,如是否啟用偏向鎖等,對象頭會有不同的設(shè)置方式。
  5. 至此,從虛擬機的角度來看,一個新的對象已經(jīng)產(chǎn)生。然而從Java程序的角度來看,對象創(chuàng)建才剛剛開始—>構(gòu)造函數(shù),即Class文件中的()方法還沒有執(zhí)行,所有的字段都為默認的零值,對象需要的其他資源和狀態(tài)信息也還沒有按照預(yù)定的意圖構(gòu)造好。一般來說,new指令之后會接著執(zhí)行()方法,按照程序員的意愿對對象進行初始化,這樣一個真正可用的對象才算完全被構(gòu)造出來。

類加載的執(zhí)行過程

網(wǎng)站的建設(shè)創(chuàng)新互聯(lián)公司專注網(wǎng)站定制,經(jīng)驗豐富,不做模板,主營網(wǎng)站定制開發(fā).小程序定制開發(fā),H5頁面制作!給你煥然一新的設(shè)計體驗!已為石雕等企業(yè)提供專業(yè)服務(wù)。
  1. 加載–主要是將.class文件中的二進制字節(jié)流讀入到新JVM中
    1. 通過類的全限定名獲取該類的二進制字節(jié)流。
    2. 將字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運行時數(shù)據(jù)結(jié)構(gòu)。
    3. 在內(nèi)存中生成一個該類的java.lang.Class對象,作為方法區(qū)這個類的各種數(shù)據(jù)的訪問入口。
  2. 連接
    1. 驗證–確保加載進來的字節(jié)流符合JVM規(guī)范
      • 文件格式驗證
      • 元數(shù)據(jù)驗證,是否符合java語言規(guī)范
      • 字節(jié)碼驗證,確保程序語義合法,符合邏輯
      • 符號引用驗證,確保下一步的解析能正常執(zhí)行
    2. 準備–為靜態(tài)變量在方法區(qū)分配內(nèi)存,并設(shè)置默認初始值
    3. 解析–虛擬機將常量池內(nèi)的符號引用替換為直接引用
      符號引用:符號引用與虛擬機實現(xiàn)的布局無關(guān),引用的目標(biāo)并不一定要已經(jīng)加載到內(nèi)存中。各種虛擬機實現(xiàn)的內(nèi)存布局各不相同,但是它們能接受的符號引用必須是一致的,因為符號引用的字面量形式明確定義在Java虛擬機規(guī)范的Class文件格式中。
      直接引用:直接引用可以是指向目標(biāo)的指針,相對偏移量或是一個能間接定位到目標(biāo)的句柄。如果有了直接引用,那引用的目標(biāo)必定已經(jīng)在內(nèi)存中存在。
  3. 初始化–標(biāo)記為常量值的字段賦值的過程,只對static修飾的變量或語句塊進行初始化。
    初始化階段是執(zhí)行類構(gòu)造器方法的過程。方法是由編譯器自動收集類中的類變量的賦值操作和靜態(tài)語句塊中的語句合并而成的。虛擬機會保證子方法執(zhí)行之前,父類的方法已經(jīng)執(zhí)行完畢,如果一個類中沒有對靜態(tài)變量賦值也沒有靜態(tài)語句塊,那么編譯器可以不為這個類生成()方法。

注意以下幾種情況不會執(zhí)行類初始化:

  1. 通過子類引用父類的靜態(tài)字段,只會觸發(fā)父類的初始化,而不會觸發(fā)子類的初始化。
  2. 定義對象數(shù)組,不會觸發(fā)該類的初始化。
  3. 常量在編譯期間會存入調(diào)用類的常量池中,本質(zhì)上并沒有直接引用定義常量的類,不會觸發(fā)定義常量所在的類。
  4. 通過類名獲取 Class 對象,不會觸發(fā)類的初始化。
  5. 通過 Class.forName 加載指定類時,如果指定參數(shù) initialize 為 false 時,也不會觸發(fā)類初始化,其實這個參數(shù)是告訴虛擬機,是否要對類進行初始化。
  6. 通過 ClassLoader 默認的 loadClass 方法,也不會觸發(fā)初始化動作。

內(nèi)存的分配方式

內(nèi)存的分配方式有以下兩種:

  1. 指針碰撞
    假設(shè)堆中內(nèi)存是絕對規(guī)整的,所有被使用過的內(nèi)存都被放在一邊,空閑的內(nèi)存放在另一邊,中間放著一個指針作為分界點的指示器,那所分配內(nèi)存就僅僅是把那個指針向空閑空間方向挪動一段與對象大小相等的距離。
  2. 空閑列表
    如果堆中內(nèi)存并不是規(guī)整的,已被使用的內(nèi)存和空閑的內(nèi)存相互交錯在一起,那就沒有辦法簡單地進行指針碰撞了,虛擬機就必須維護一個列表,記錄上哪些內(nèi)存塊是可用的,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,并更新列表上的記錄。

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

因此,當(dāng)使用Serial、ParNew等帶壓縮整理過程的收集器時,系統(tǒng)采用的分配算法是指針碰撞,即簡單又高效。
而當(dāng)使用CMS這種基于清除(Sweep)算法的收集器時,理論上就只能采用較為復(fù)雜高效的空閑列表來分配內(nèi)存。

指針碰撞方式存在的問題:
對象創(chuàng)建在虛擬機中是非常頻繁的行為,僅僅修改一個指針?biāo)赶虻奈恢?,在并發(fā)情況下也并不是線程安全的。
可能會出現(xiàn)正在給對象A分配內(nèi)存,指針還沒來得及修改,對象B又同時使用了原來的指針來分配內(nèi)存的情況。解決這個問題有兩種可選方案:

  1. 對分配內(nèi)存空間的動作進行同步處理—實際上虛擬機是采用CAS配上失敗重試的方式保證更新操作的原子性。
  2. 把內(nèi)存分配的動作按照線程劃分在不同的空間之中進行,即每個線程在Java堆中預(yù)先分配一小塊內(nèi)存,稱為本地線程分配緩沖(TLAB),哪個線程要分配內(nèi)存,就在哪個線程的本地緩沖區(qū)中分配,只有本地緩沖區(qū)用完了,分配新的緩沖區(qū)時才需要同步鎖定。

對象的內(nèi)存布局

由于Java面向?qū)ο蟮乃枷?,在JVM中需要大量存儲對象,存儲時為了實現(xiàn)一些額外的功能,需要在對象中添加一些標(biāo)記字段用于增強對象功能,這些標(biāo)記字段組成了對象頭。
Hotspot虛擬機的對象頭主要包括兩部分數(shù)據(jù):Mark Word(標(biāo)記字段)、Klass Pointer(類型指針)
MarkWord:默認存儲對象的HashCode,分代年齡和鎖標(biāo)志位信息。這些信息都是與對象自身定義無關(guān)的數(shù)據(jù),所以Mark Word被設(shè)計成一個非固定的數(shù)據(jù)結(jié)構(gòu)以便在極小的空間內(nèi)存存儲盡量多的數(shù)據(jù)。它會根據(jù)對象的狀態(tài)復(fù)用自己的存儲空間,也就是說在運行期間Mark Word里存儲的數(shù)據(jù)會隨著鎖的標(biāo)志位的變化而變化。
Klass Point:對象指向它的類元數(shù)據(jù)的指針,虛擬機通過這個指針來確定這個對象是哪個類的實例。

實例數(shù)據(jù)部分是對象真正存儲的有效信息,即我們在程序代碼里面所定義的各種類型的字段內(nèi)容,無論是從父類繼承下來的還是在子類中定義的字段都必須記錄起來。

對其填充不是必然存在的,也沒有特別的含義,它僅僅起占位符的作用。由于任何對象的大小都必須是8字節(jié)的整數(shù)倍,如果對象實例數(shù)據(jù)部分沒有對齊的話,就需要通過對齊填充來補全。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


網(wǎng)頁題目:【Java語言】對象的創(chuàng)建過程詳細說明-創(chuàng)新互聯(lián)
文章分享:http://weahome.cn/article/dgjici.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部