上回說到Jvm內存的分配,猶如劃地分治,把一塊本機內存分裂成了6塊。
這回我們就講講java堆的詳細信息
java堆裏也不是鐵板一塊,類似jvm的分治,java堆內部也好不到哪裏去,大致上可以分成新生代和老年代,他們內部也不和諧,新生代又可以細分爲Eden和兩個survivor空間。
(按照複製算法畫圖並解析,其他算法請見第四章)圖片如下:
是不是看着大小比例很彆扭呢,沒辦法呀,就是按照內存大小畫的-。-iii
至於他們的作用的,請關注博客,下回分解。那麼回到原題,我們分解了java堆的內部情況,接下來是不是就要講對象的分配過程了?
yeah,對象怎麼分配的呢?(默認以hotspot 虛擬機爲例)
在hotspot中把對象分成了對象頭,實例數據和對齊填充。
在對象頭中包括了兩部分分別是:
1、存儲對象自身的運行時數據:hashcode,GC分代年齡信息(後面會詳細說明),鎖標誌等等。
2、類型指針:它指向它的類,沒錯就是關在方法區的那傢伙。(個別例外沒有,如數組)
在實例數據中才是乾貨:
定義的各種類型的字段內容(包括父類繼承)。
還有一部分是對齊補充
因爲內存管理的系統要求對象起始地址必須是8字節的整數倍,如果對象不能正好8字節整數倍結束只能湊了。
好了,對象的問題解決了,那麼我們分配了總不能不用吧,那麼我們該怎麼找到我們的對象呢?
想想我們我們什麼時候喜歡使用對象呢?在方法中調用!像這樣XXX.xxx();對嗎?
還記得方法被關在哪了嗎?不記得請回去看看第一篇,謝謝。
好,你不看我就告訴你吧,方法在調用的時候被轉化成棧幀,放在了方法棧裏。在方法棧裏調用的對象是被存儲成reference數據的,這個reference可以看成一個指針,其實它也就是個指針,在JVM規範中它被規定成了指向對象的引用。我們拿到這個reference的內容就能找到對象的內存地址了。
不對!現在男女比例這個鳥樣,程序猿想找對象哪有那麼簡單?
這就要看你是什麼虛擬機了?你要是高富帥虛擬機還是簡單的,你找對象估計就是這個過程:
但是屌絲虛擬機怎麼辦?屌絲找對象都說是個女的就行。。一般也找不着。。最後還不是都是靠媒婆(句柄)
當然它們各有各的好處,不然也不會同時存在。
高富帥虛擬機他比較省時間,直接找對象哪,不要媒婆在中間當然會節省時間,但是這種自己談的對象感情深啊,每次對象出差都要揪心(對象在堆中GC時會被移動,每次移動都需要修改reference的數據)
屌絲虛擬機找對象是慢了點,但是大家感情都不深,對象出去出個差也不是那麼揪心,只要在句柄那修改一下就好了。