做網(wǎng)絡(luò)推廣的網(wǎng)站有哪些如何做電商 個(gè)人
Java內(nèi)存模型
對(duì)象內(nèi)存中可以分為三塊區(qū)域:對(duì)象頭(Header),實(shí)例數(shù)據(jù)(Instance Data)和對(duì)齊填充(Padding),以64位操作系統(tǒng)為例(未開(kāi)啟指針壓縮的情況)Java對(duì)象布局
如下圖所示:
其中對(duì)象頭中的Mark Word中的詳細(xì)信息在文章synchronized鎖升級(jí)原理中有詳細(xì)介紹。上圖中的對(duì)齊填充不是一定有的,如果對(duì)象頭和實(shí)例數(shù)據(jù)加起來(lái)剛好是8字節(jié)的倍數(shù),那么就不需要對(duì)齊填充。
Object obj=new Object()占用字節(jié)
這是網(wǎng)上很多人都會(huì)提到的一個(gè)問(wèn)題,那么結(jié)合上面的Java內(nèi)存布局,我們來(lái)分析下,以64位操作系統(tǒng)為例,new Object()占用大小分為兩種情況:
- 未開(kāi)啟指針壓縮 占用大小為:8(Mark Word)+8(Class Pointer)=16字節(jié)
- 開(kāi)啟了指針壓縮(默認(rèn)是開(kāi)啟的) 開(kāi)啟指針壓縮后,Class Pointer會(huì)被壓縮為4字節(jié),最終大小為:8(Mark Word)+4(Class Pointer)+4(對(duì)齊填充)=16字節(jié)
結(jié)果到底是不是這個(gè)呢?我們來(lái)驗(yàn)證一下。首先引入一個(gè)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;public class HeapMemory {public static void main(String[] args) {Object obj = new Object();System.out.println(ClassLayout.parseInstance(obj).toPrintable());}
}
輸出結(jié)果如下:
最后的結(jié)果是16字節(jié),沒(méi)有問(wèn)題,這是因?yàn)?*默認(rèn)開(kāi)啟了指針壓縮
**,那我們現(xiàn)在把指針壓縮關(guān)閉之后再去試試。
-XX:+UseCompressedOops 開(kāi)啟指針壓縮
-XX:-UseCompressedOops 關(guān)閉指針壓縮
得到如下結(jié)果:
可以看到,這時(shí)候已經(jīng)沒(méi)有了對(duì)齊填充部分了,但是占用大小還是16位。
以上是Object 內(nèi)無(wú)任何成員變量的情況
如果有成員變量,以下是成員變量數(shù)據(jù)類型占用字節(jié)大小情況
類型 | 存儲(chǔ) | 取值范圍 |
---|---|---|
int | 4byte | -2^31 ~ 2^31 - 1 |
short | 2byte | -2^15 ~ 2^15 - 1 |
long | 8byte | (-2)^63 ~ 2^63 - 1 |
byte | 1byte | -128 ~ 127 |
float | 4byte | |
double | 8byte | |
boolean | 1byte | |
char | 2byte |
Hotspot實(shí)現(xiàn)的JVM開(kāi)啟內(nèi)存壓縮的規(guī)則(64位機(jī)器):
- 4G以下,直接砍掉高32位
- 4G~32G,默認(rèn)開(kāi)啟內(nèi)存壓縮
- 32G以上,壓縮無(wú)效,使用64位
下面我們?cè)賮?lái)演示一下如果一個(gè)對(duì)象中帶有屬性之后的大小。
新建一個(gè)類,內(nèi)部只有一個(gè)byte屬性:
package com.zwx.jvm;public class MyItem {byte i = 0;
}
然后分別在開(kāi)啟指針壓縮和關(guān)閉指針壓縮的場(chǎng)景下分別輸出這個(gè)類的大小。
package com.zwx.jvm;import org.openjdk.jol.info.ClassLayout;public class HeapMemory {public static void main(String[] args) {MyItem myItem = new MyItem();System.out.println(ClassLayout.parseInstance(myItem).toPrintable());}
}
開(kāi)啟指針壓縮,占用16字節(jié):
關(guān)閉指針壓縮,占用24字節(jié):
這個(gè)時(shí)候就能看出來(lái)開(kāi)啟了指針壓縮的優(yōu)勢(shì)了,如果不斷創(chuàng)建大量對(duì)象,指針壓縮對(duì)性能還是有一定優(yōu)化的。