<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      深入理解JVM(③)HotSpot虛擬機對象探秘

      前言

      上篇文章介紹了Java虛擬機的運行時數(shù)據(jù)區(qū)域,大致明白了Java虛擬機內(nèi)存模型的概況,下面就基于實用優(yōu)先的原則,以最常用的虛擬機HotSpot和最常用的內(nèi)存區(qū)域Java堆為例,升入探討一下HotSpot虛擬機在Java堆中對象分配、布局和訪問的全過程。

      對象的創(chuàng)建

      Java是一門面向?qū)ο蟮木幊陶Z言,在Java程序的運行過程中每時每刻都有對象被創(chuàng)建出來,那么在虛擬機中,對象的創(chuàng)建是怎樣的一個過程呢?
      當(dāng)Java虛擬機遇到一條字節(jié)碼new指令時,首先檢查這個指令的參數(shù)是否能定位到一個類的符號引用,然后檢查這個類是否已經(jīng)被加載、解析和初始化過。如果沒有,那么先執(zhí)行類型的加載過程。

      為對象分配空間

      在類加載檢查通過后,接下來虛擬機將為新生對象分配內(nèi)存。為對象分配空間的任務(wù)實際上便等同于把一塊確定大小的內(nèi)存塊兒從Java堆中劃分出來。
      在解釋Java堆是如何為對象分配空間的時候,先解釋兩個虛擬機常用的分配空間方式。

      • 指針碰撞
        當(dāng)一塊兒內(nèi)存中的空間是絕對規(guī)整的時候,就是說,所有被使用過的內(nèi)存放在一邊,空閑的內(nèi)存放在另一邊,中間放著一個指針,作為分界點的指示器,當(dāng)分配內(nèi)存是,就僅僅是把指針向空閑的方向挪動一段與對象大小相等的距離,這種分配方式稱為“指針碰撞”(Bump The Pointer)。
      • 空閑列表
        當(dāng)一塊兒內(nèi)存的空間不是規(guī)整的時候,已被使用的內(nèi)存和空閑的內(nèi)存相互交錯在一起,那就沒辦法簡單地進(jìn)行指針碰撞了,虛擬機就必須維護(hù)一個列表,記錄哪些內(nèi)存塊是可用的,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,并更新列表上的記錄,這種分配方式稱為“空閑列表”(Free List)。
        具體選擇哪種分配方式,是由Java堆中的內(nèi)存空間是否規(guī)則來決定的,而Java堆是否規(guī)整有由所采用的垃圾收集器是否帶有空間壓縮整理的能力決定。所以,當(dāng)使用Serial、ParNew等帶壓縮整理過的的收集器是,對象的分配方式是指針碰撞,而當(dāng)使用CMS這種基于清除算法的收集器是,理論上就只能采用較為復(fù)雜的空閑列表來分配內(nèi)存。

      對象創(chuàng)建的線程安全

      在對象創(chuàng)建的時候,除了如何劃分可用空間外,還有一個問題,那就是在分配內(nèi)存空間的時候如何保證線程安全。
      解決這個問題有兩種方案:

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

      在保證了線程安全的為對象分配了內(nèi)存空間后,從虛擬機的視角來看,一個新的對象已經(jīng)產(chǎn)生了。
      但是從Java程序的視角看來,對象創(chuàng)建才剛剛開始,構(gòu)造函數(shù),也就是Class文件中的< init >方法還沒有執(zhí)行,new 指令之后會執(zhí)行< init >方法,
      按照程序員的意愿對對象進(jìn)行初始化,這樣一個真正可用的對象才算完全被構(gòu)造出來。

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

      在HotSpot虛擬機里,對象在堆內(nèi)存中的存儲布局可以劃分為三個部分:對象頭(Header)實例數(shù)據(jù)(Insetance Data) 和對齊填充(Padding)

      對象頭

      HotSpot虛擬機對象的對象頭包括兩類信息。

      • 第一類是用于存儲對象自身運行時數(shù)據(jù),如哈希碼(HashCode)、GC分代年齡、鎖狀態(tài)標(biāo)志等。這部分?jǐn)?shù)據(jù)的長度在32位和64位的虛擬機中分別為32個比特和64個比特,稱為 “ Mark Word ” 。
      • 對象頭的另外一部分是類型指針,即對象指向它的類型元數(shù)據(jù)的指針,Java虛擬機通過這個指針來確定該對象是哪個類的實例。如果對象是一個Java數(shù)組,那在對象頭中還必須有一塊用于記錄數(shù)組長度的數(shù)據(jù),因為需要通過數(shù)組的長度來確定對象的大小。

      實例數(shù)據(jù)

      實例數(shù)據(jù)是對象真正存儲的有效信息,即我們在程序代碼里面所定義的各種類型的字段內(nèi)容,無論是從父類繼承下來的,還是在子類中定義的字段都必須記錄起來。這部分的存儲順序會受到虛擬機分配策略參數(shù)(-XX:FieldsAllocationStyle參數(shù))和字段在Java源碼中定義順序的影響。

      對齊填充

      由于HotSpot虛擬機的自動內(nèi)存管理系統(tǒng)要求對象起始地址必須是8字節(jié)的整數(shù)倍,換句話說就是任何對象的大小都必須是8字節(jié)的整數(shù)倍。對象頭部分已經(jīng)被精心設(shè)計成正好是8字節(jié)的倍數(shù)(1倍或2倍),因此如果對象實例數(shù)據(jù)部分沒喲對齊的話就需要通過對齊填充來補全。所以對齊填充為,并不是必然存在的一部分占位符。

      對象的訪問定位

      對象創(chuàng)建完成后就可以使用了,對象的定位是根據(jù)棧中的引用數(shù)據(jù),來確定對象在內(nèi)存中的位置的。那么如何通過引用數(shù)據(jù)定位到堆中的對象位置呢?
      主流的訪問方式主要有使用句柄直接指針兩種:

      • 如果使用句柄訪問的話,Java堆中將可能會劃分出一塊內(nèi)存來作為句柄池,引用數(shù)據(jù)中存儲的就是對象的句柄地址,而句柄中包含了對象實例數(shù)據(jù)與類型數(shù)據(jù)各自具體的地址信息。
      • 如果使用直接指針訪問的話,Java堆中對象的內(nèi)存布局就必須考慮如何放置訪問類型數(shù)據(jù)的相關(guān)信息,引用數(shù)據(jù)中存儲的直接就是對象地址,這樣訪問對象更快捷。

      使用句柄,在對象被移動(垃圾收集時)時只會改變句柄中的數(shù)據(jù)指針,而直接指針節(jié)省了一次指針定位的時間開銷速度更快!

      posted @ 2020-02-02 22:22  紀(jì)莫  閱讀(515)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲国产日韩一区三区| 激情在线网| 顶级少妇做爰视频在线观看| 南丰县| 日韩大片高清播放器| 国产区精品视频自产自拍| 成人乱人伦精品小说| 成人自拍短视频午夜福利| 塔河县| 噜噜噜噜私人影院| 人妻在线中文字幕| 午夜三级成人在线观看| 欧美www在线观看| 在线视频中文字幕二区| 高清免费毛片| 艳妇乳肉豪妇荡乳在线观看| 国产麻传媒精品国产av| 国产亚洲精品第一综合麻豆| 羞羞影院午夜男女爽爽免费视频| 丁香花在线影院观看在线播放| 国产av综合影院| 亚洲夂夂婷婷色拍WW47| 色爱综合另类图片av| 国产精品三级在线观看无码| 日本亚洲色大成网站www久久| 极品少妇无套内射视频| 成年性午夜免费视频网站| 午夜福利理论片高清在线| 亚洲熟女国产熟女二区三区| 国产成人精品中文字幕| 日韩高清在线亚洲专区不卡| 一道本AV免费不卡播放| 久久久久国产精品熟女影院| 国产免费性感美女被插视频| 99国产精品自在自在久久| 亚洲国产精品男人的天堂| 国产综合久久久久久鬼色| 成人免费无码av| 国产精品中文字幕在线| 边坝县| 亚洲男人第一无码av网|