float占几个字节_一个HashMap对象占多少字节?
對(duì)象=對(duì)象頭+成員變量+對(duì)齊填充
對(duì)象頭結(jié)構(gòu):java對(duì)象在Heap里面的結(jié)構(gòu)是這樣的:對(duì)象頭跟對(duì)象體,對(duì)象體跟C里面的結(jié)構(gòu)體是一樣的,對(duì)象頭由兩個(gè)域組成:用于存放hashcode、同步、GC的_mask域,和指向方法區(qū)該對(duì)象Class對(duì)象的指針——_klass域,對(duì)于64位系統(tǒng),頭部長(zhǎng)度理論上講應(yīng)該是8+8=16字節(jié)。但是從java6u23以后開始,64位的機(jī)器會(huì)自動(dòng)開啟指針壓縮的功能,此時(shí)引用指針的長(zhǎng)度為4字節(jié)。所以,對(duì)象頭長(zhǎng)度應(yīng)該為8+4=12。
成員變量:分兩類,包括一些基本類型,如int,long.byte,short,boolean等,以及引用類型,如String,Date引用。如果是引用類型,也應(yīng)該把引用類型指向的對(duì)象納入當(dāng)前對(duì)象。
對(duì)齊填充:JVM規(guī)定,對(duì)象的大小必須是8字節(jié)的整數(shù)倍,如果不足,則會(huì)補(bǔ)齊。
此外,對(duì)于數(shù)組,還會(huì)有一個(gè)標(biāo)示數(shù)組長(zhǎng)度的字段。其實(shí)數(shù)組也是一種類,會(huì)在后文中介紹。
以此為理論基礎(chǔ),我們來計(jì)算一下常用的對(duì)象占用空間大小。
Integer
類結(jié)構(gòu)圖:可以看到,只有一個(gè)私有的int型數(shù)據(jù)
所以Integer長(zhǎng)度為:頭(8+4)+ int(4) = 16字節(jié)
Long
類結(jié)構(gòu)圖
類似于Integer,只有一個(gè)long型的私有成員。
所以總長(zhǎng)度為:頭(8+4)+long(8)+padding(4)=24字節(jié)
Object
類結(jié)構(gòu)圖
沒有成員變量,所以占用空間頭(8+4)+padding(4)=16字節(jié)
String:“string”
類結(jié)構(gòu)圖
這個(gè)結(jié)構(gòu)稍微有點(diǎn)復(fù)雜,涉及到了數(shù)組成員。其實(shí)數(shù)組也是一種類型,只不過這種類型是JVM在運(yùn)行時(shí)生成的類型,并不在class文件中定義,我們將其當(dāng)做一種特殊的類就可以了。既然涉及到了成員變量是對(duì)象,那么,我們就要把String分成兩部分來計(jì)算:
String類型:頭部(8+4)+int(4)+int(4)+指向char[]對(duì)象的引用類型(4)=24字節(jié)
char[]類型:數(shù)組類型比普通對(duì)象多一個(gè)標(biāo)示數(shù)組長(zhǎng)度的字段,占4個(gè)字節(jié)。對(duì)于字符串“String”來說,頭部(8+4)+數(shù)組長(zhǎng)度(4)+“String”(2*6)+padding(4)=32字節(jié)
因此,它的總占用空間為56字節(jié)
ArrayList
類結(jié)構(gòu)圖
其實(shí),還有一個(gè) modCount成員,繼承自AbstractList類,那么對(duì)于一個(gè) list = new ArrayList(); list.add("String");的list來說,它擁有兩個(gè)int,一個(gè)大小為10的數(shù)組(當(dāng) list.add() 第一個(gè)元素的時(shí)候,它會(huì)初始化elementData為一個(gè)長(zhǎng)度10的數(shù)組)
ArrayList: 頭部(8+4)+int(4)+int(4)+數(shù)組引用(4)=24字節(jié)
elementData[] : 頭部(8+4)+長(zhǎng)度(4)+string引用(4*10)=56字節(jié)
"String"字符串:這個(gè)我們之前計(jì)算過了,為56字節(jié)
所以,總空間大小為24+56+56=136字節(jié)
HashMap
類結(jié)構(gòu)圖
HashMap內(nèi)部結(jié)構(gòu)比較復(fù)雜,除了一些基本的類型,還有比較復(fù)雜一點(diǎn)的集合類型。如table,是一個(gè)Entry數(shù)組,用來存放鍵值對(duì),所有put進(jìn)map中key-value都會(huì)被封裝成一個(gè)entry放入到table中去。而還有一些輔助對(duì)象,如entry,繼承自AbstractMap的keySet,values,這些都是在遍歷map元素時(shí)用到的集合,他們的主要功能是通過在自己內(nèi)部維護(hù)一個(gè)迭代器向外輸出table中的數(shù)據(jù),并不實(shí)際儲(chǔ)存key-value數(shù)據(jù)。
以 ?Map map = new HashMap(); 這時(shí)候我們計(jì)算一下他的占用空間情況:
總空間為:48+16=64字節(jié)
hashmap:頭部(8)+int(4*4)+float(4)+table數(shù)組引用(4)+entrySet引用(4)+keySet引用(4)+values引用(4)+padding(4)=48字節(jié)
table:頭部(8+4)+長(zhǎng)度(4)=16字節(jié)
然后我們put進(jìn)去一條數(shù)據(jù):map.put( "100002", "張明");
當(dāng)HashMap初始化的時(shí)候,他會(huì)開辟一個(gè)長(zhǎng)度為16的table數(shù)組,每當(dāng)put一個(gè)新的key-value的時(shí)候,他會(huì)根據(jù)當(dāng)前threshold來判斷是否需要擴(kuò)容,如果需要擴(kuò)容,則會(huì)以倍數(shù)增長(zhǎng)的方式擴(kuò)容table數(shù)組。如16、32、64.具體原理請(qǐng)參考 http://blog.csdn.net/zq602316498/article/details/39351363
接下來讓我們計(jì)算一下這個(gè)map多占用的空間
hashmap:頭部(8)+int(4*4)+float(4)+table數(shù)組引用(4)+entrySet引用(4)+keySet引用(4)+values引用(4)+padding(4)=48字節(jié)
table: 80+32+16+16+56+48+0= 216字節(jié)
table:頭部(8+4)+長(zhǎng)度(4)+entry(4*16)=80字節(jié)
entry:頭部(8+4)+k(4)+value(4)+next(4)+int(4)+padding(4)=32字節(jié)
key(String):56字節(jié)
value(String) :48字節(jié)
next :因?yàn)榫椭挥幸粋€(gè)元素,所以next值為null,0字節(jié)
entrySet:為空指針,0字節(jié)
keySet:空指針,0字節(jié)
values:空指針,0字節(jié)
綜上分析,這個(gè)map占用48+216+0+0+0=264字節(jié)
然后我們繼續(xù)調(diào)用 map.keySet() 方法,此時(shí),keySet會(huì)被賦予一個(gè)類型為 HashMap$KeySet 的對(duì)象,這個(gè)對(duì)象的結(jié)構(gòu)如下:
可以看到,它并不復(fù)雜,只是用來遍歷map key集合的一個(gè)工具類,
keySet :頭部(8+4)+padding(4)=16字節(jié)
所以,總大小為264+16=280字節(jié)
然后我們繼續(xù)調(diào)動(dòng) map.values(),和上面類似
values : 頭部(8+4)+padding(4)=16字節(jié)所以,總大小為 280+16=296字節(jié)
然后我們繼續(xù)調(diào)用 map.entrySet(),
entrySet:頭部(8+4)+padding(4)=16字節(jié)
所以總大小為 296+16=312字節(jié)
長(zhǎng)按掃碼關(guān)注我!
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的float占几个字节_一个HashMap对象占多少字节?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bp神经网络代码_机器学习(周志华)课后
- 下一篇: python编程基础人民邮电出版社_Py