<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ### 對象的指向 先來看一段代碼: ~~~ package?com.zwx.jvm; public?class?HeapMemory?{ ????private?Object?obj1?=?new?Object(); ????public?static?void?main(String[]?args)?{ ????????Object?obj2?=?new?Object(); ????} } ~~~ 上面的代碼中,obj1 和obj2在內存中有什么區別? 我們先來回憶一下JVM系列1的文章中有提到,方法區存儲每個類的結構,比如:運行時常量池、屬性和方法數據,以及方法和構造函數等數據。所以我們這個obj1是存在方法區的,而new會創建一個對象實例,對象實例是存儲在堆內的,于是就有了下面這幅圖(**方法區指向堆**): ![](https://img.kancloud.cn/c4/f8/c4f8a7f98f59e4bf621f6d8ee603fae3_560x278.png) 而obj2 是屬于方法內的局部變量,存儲在Java虛擬機棧內的棧幀中的局部變量表內,這就是經典的**棧指向堆**: ![](https://img.kancloud.cn/9c/aa/9caadb1b451053cecc4125ba0c0c750b_789x431.png) 這里我們再來思考一下,我們一個變量指向了堆,而堆內只是存儲了一個實例對象,那么堆內的示例對象是如何知道自己屬于哪個Class,也就是說這個實例是如何知道自己所對應的類元信息的呢?這就涉及到了一個Java對象在內存中是如何布局的 ### Java內存模型 對象內存中可以分為三塊區域:對象頭(Header),實例數據(Instance Data)和對齊填充(Padding),**以64位操作系統為例(未開啟指針壓縮的情況)**Java對象布局如下圖所示: ![](https://img.kancloud.cn/39/49/394970c1e42926bcc2d139ad75c1150f_833x282.png) 其中對象頭中的Mark Word中的詳細信息在文章synchronized鎖升級原理中有詳細介紹。上圖中的對齊填充不是一定有的,如果對象頭和實例數據加起來剛好是8字節的倍數,那么就不需要對齊填充 ### [Object obj=new Object()占用字節] 這是網上很多人都會提到的一個問題,那么結合上面的Java內存布局,我們來分析下,以64位操作系統為例,new Object()占用大小分為兩種情況: * 未開啟指針壓縮 ? ? 占用大小為:**8(Mark Word)+8(Class Pointer)=16字節** * 開啟了指針壓縮(默認是開啟的) ? ? 開啟指針壓縮后,Class Pointer會被壓縮為4字節,最終大小為:**8(Mark Word)+4(Class Pointer)+4(對齊填充)=16字節** 結果到底是不是這個呢?我們來驗證一下。首先引入一個pom依賴: ~~~ <dependency>???? <groupId>org.openjdk.jol</groupId>???? <artifactId>jol-core</artifactId>???? <version>0.10</version> </dependency> ~~~ ``` package?com.zwx.jvm; import?org.openjdk.jol.info.ClassLayout; publicclass?HeapMemory?{ public?static?void?main(String\[\]?args)?{ ????????Object?obj?=?new?Object(); ????????System.out.println(ClassLayout.parseInstance(obj).toPrintable()); ????} } ``` 輸出結果如下: ![](https://img.kancloud.cn/5b/3b/5b3b82c44bf65757a7e93b3b5e18f560_1058x265.png) 最后的結果是16字節,沒有問題,這是因為默認開啟了指針壓縮,那我們現在把指針壓縮關閉之后再去試試 ![](https://img.kancloud.cn/85/e2/85e21102e228867d2624262ce1df9424_770x180.png) 再次運行,得到如下結果: ![](https://img.kancloud.cn/de/a4/dea48971cdbcc84e2c0063894bc37a71_1014x269.png) 可以看到,這時候已經沒有了對齊填充部分了,但是占用大小還是16位。 下面我們再來演示一下如果一個對象中帶有屬性之后的大小。 新建一個類,內部只有一個byte屬性: ![](https://img.kancloud.cn/08/3d/083dc37d17a02aad365d107d6fd8282a_1322x1030.png) 開啟指針壓縮,占用16字節: ![](https://img.kancloud.cn/3c/cd/3ccd850e2d74f8bf397ab8971ec78f66_1062x266.png) 關閉指針壓縮,占用24字節: ![](https://img.kancloud.cn/27/c0/27c0b6422c077f4890af15bea660b371_1080x292.png) 這個時候就能看出來開啟了指針壓縮的優勢了,如果不斷創建大量對象,指針壓縮對性能還是有一定優化的
                  <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>

                              哎呀哎呀视频在线观看