<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 1.背景與大綱   在我們了解了java虛擬機的運行時數據區后,我們大概知道了虛擬機內存的概況,但是我們還是不清楚具體怎么存放的訪問的;   接下來,我們將深入探討HotSport虛擬機在java堆中對象的分配、布局、訪問的全過程。 # 2.對象創建   ![](https://img.kancloud.cn/76/3f/763fe00c0772fa696f91e55e066eed60_747x372.png)   1.類加載:當遇到new指令時,先判斷這個類是否被加載、解析、初始化過,如果沒有,先執行相應類的加載過程(后面會詳細分析這個過程)。   2.分配內存:   如果Java堆內存是規整連續的,采用“指針碰撞”的分配方式,   ![](https://img.kancloud.cn/d1/bf/d1bf1c1849def36a2ea299f9be3fa70c_448x253.png)   如果是不連續規整的,采用“空閑列表”分配方式。如下圖:灰色表示已使用,數字表示可用   ![](https://img.kancloud.cn/09/52/09527213a3a4e16285f922cbd772acf6_676x319.png)   內存是否規整取決于垃圾收集器是否帶有壓縮整理功能。   Serial,ParNew等帶有Compact過程的收集器,采用的分配算法是“指針碰撞”。   而CMS這種基于Mark-Sweep算法的收集器,通常采用“空閑列表”分配方式。   線程安全問題:即便是修改指針指向位置,A\\B兩個線程有可能會指向同一個地址   ![](https://img.kancloud.cn/9f/04/9f04a52af161272b6586f2081a4d5fbd_667x318.png)   解決方案:   a.同步鎖:   b.TLAB:本地線程分配緩沖,把內存的分配動作按照線程劃分在不同的空間進行   等TLAB用完分配新的TLAB時,才需要同步鎖   虛擬機是否使用TLAB,可以通過-XX:+/UseTLAB參數設定   ![](https://img.kancloud.cn/15/37/1537f67d355aa601a40668cf5f6fb395_589x282.png)   3.對象初始化為零對象: *  a.如果使用的是TLAB,這一步可以提前到TLAB分配的時候進行   b.作用:保證了實例字段在java代碼中可以不賦初始值就可以直接使用*   4.對象頭進行設置,   包括這個對象是哪個類的實例、如何才能找到類的元數據信息、對象的哈希碼、對象的GC分代年齡等信息。   5.java程序初始化,最后執行init方法,把對象按照程序員的意愿進行初始化。這樣一個真正可用的對象才算完全生產出來。 # 3.對象內存布局     ![](https://img.kancloud.cn/b4/b5/b4b5414397e0b536897e20a587b22bc2_633x530.png)   對象內存布局分為三塊區域 ## 3.1.對象頭(Header)   對象頭主要包括:運行時數據、類型指針 ### 3.1.1.運行時數據   對象頭,存儲對象自身的運行時數據,如哈希碼、對象的GC分代年齡、鎖狀態標志、偏向線程ID、偏向時間戳,   1.這部分數據的長度在32位和64位虛擬機中,分別為32bit和64bit。   2.官方稱其為:Mark Word   3.存儲的運行時數據過多(超出32bit、64bit)   4.Mark Word被設計成為一個非固定數據結構,以便在極小的空間內存存儲盡量多的信息   ![](https://img.kancloud.cn/0e/f7/0ef706e36bfe2b061153dfd0eb51366b_787x279.png)   5.根據對象的狀態復用自己的存儲空間 ### ?3.1.2.類型指針   另一個部分是類型指針   1.定義:對象指向它的類元數據的指針   2.作用:虛擬機通過這個指針來確定這個對象是哪個類的實例   3.但是:并不是所有的虛擬機實現都必須在對象上保留類型指針   4.結論:查找對象的元數據信息并不一定要經過對象本身(下一節詳細講) ### 3.1.3.特例   另外,如果對象是java數組   1.對象頭必須有一塊用于記錄數組長度的數據   2.原因:普通java對象的元數據信息可以確定java對象的大小   3.但是,從數組的元數據中卻無法確定數組的大小 ## 3.2.實例數據(Instance Data)   1.存儲內容:是對象真正存儲的有效信息,也是在程序代碼中所定義的各種類型的字段內容   2.存儲范圍:無論是父類還是子類都要記錄   3.存儲順序:存儲順序會受到虛擬機分配策略參數(fieldsAllocationStyle)和字段定義順序的影響   4.默認分配策略順序:按字節由大到小(即由寬到窄),   longs/doubles->ints->shorts/chars->bytes/booleans->oops(Ordinary Object Pointers)普通對象指針   5.在滿足分配策略這個前提條件下,父類中定義的變量會出現在子類之前   6.如果CompactFields參數值為true,那么子類中較窄的變量也可能會插入到父類變量的空隙之中 ## 3.3.對齊補充(Padding)   1.作用:對齊填充并不是必然存在的,也沒有特別的含義,它僅僅起著占位符的作用。   2.原因:由于HotSpot VM的自動內存管理系統要求對象起始地址必須是8字節的整數倍,換句話說,就是對象的大小必須是8字節的整數倍。   3.解決:而對象頭部分正好是8字節的倍數(1倍或者2倍),因此,當對象實例數據部分沒有對齊時,就需要通過對齊填充來補全。 # 4.對象的訪問定位   ![](https://img.kancloud.cn/47/97/4797ad8cfe805a975e0d06503002c432_747x268.png)   對象的訪問定位   1.Java程序需要通過棧上的reference數據來操作堆上的具體對象。   2.由于reference類型在Java虛擬機規范中只規定了一個指向對象的引用,   3.并沒有定義這個引用應該通過何種方式去定位、訪問堆中的對象的具體位置,   4.所以對象訪問方式也是取決于虛擬機實現而定的。   5.目前主流的訪問方式有使用句柄和直接指針兩種。   6.總結:通過reference數據來定位具體對象,但reference只規定了對象的引用,并沒有提供具體實現   ![](https://img.kancloud.cn/9b/bb/9bbb6da3faadc3b14bbda26098e80733_908x581.png) ## 4.1.句柄方式   1.Java堆中將會劃分出一塊內存來作為句柄池,   2.reference中存儲的就是對象的句柄地址,   3.而句柄中包含了對象實例數據與類型數據各自的具體地址信息。   優點:   使用句柄來訪問的最大好處就是reference中存儲的是穩定的句柄地址,   在對象被移動(垃圾收集時移動對象是非常普遍的行為)時只會改變句柄中的實例數據指針,而reference本身不需要修改。 ## 4.2.直接指針方式   1.Java堆對象的布局中就必須考慮如何放置訪問類型數據的相關信息,   2.而reference中存儲的直接就是對象地址。   優點:   使用直接指針訪問方式的最大好處就是速度更快,它節省了一次指針定位的時間開銷,   由于對象的訪問在Java中非常頻繁,因此這類開銷積少成多后也是一項非常可觀的執行成本。 ## 4.3.案例   虛擬機Sun HotSpot 使用的是直接指針的方式!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看