JAVA運(yùn)行時(shí)—內(nèi)存分配情況

對象的內(nèi)存布局

  • 在HotSpot虛擬機(jī)中,對象在內(nèi)存中存儲(chǔ)的布局可以分為3塊區(qū)域:對象頭(Header)、實(shí)例數(shù)據(jù)(Instance Data)、對齊填充(Padding)。
    • 對象頭包括兩部分信息:
      • 第一部分用于存儲(chǔ)對象的自身的運(yùn)行時(shí)數(shù)據(jù),如哈希碼(HashCode)、GC分代年齡、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程ID等。
    • 第二部分是類型指針,即對象指向它的類元數(shù)據(jù)(存放在方法區(qū))的指針,虛擬機(jī)通過這個(gè)指針來確定這個(gè)對象是哪個(gè)類的實(shí)例。
  • 實(shí)例數(shù)據(jù)部分:是對象真正存儲(chǔ)的有效信息,也是在程序代碼中所定義的各種類型的字段內(nèi)容。無論是從父類繼承下來的,還是在子類中定義的,都需要記錄起來。
  • 對齊填充:略。

對象的訪問定位

概述:建立對象是為了使用對象,我們的Java程序需要通過棧上的reference數(shù)據(jù)來操作堆上的具體對象。目前主流的訪問方式有使用句柄直接指針兩種。

  • 直接指針訪問方式的最大好處就是速度更快,它節(jié)省了一次指針定位的時(shí)間開銷,由于對象的訪問在Java中非常頻繁,HotSpot采用的便是這種方式。
  • 下圖即為Java利用直接指針訪問對象:
Paste_Image.png

實(shí)例分析###

public class Dog{
    private int age;
    
    public Dog() {
    }
    
    public Dog(int age){
        this.age = age;
    }
    
    public int getAge() {
        return age;
    }
    
    public static void main(String[] args)  {
        Dog dog = new Dog();
        ...
    }
}
  • 內(nèi)存分配圖如下
Paste_Image.png
  • 重點(diǎn)內(nèi)容說明
  • 構(gòu)造方法or實(shí)例方法:需要將this指針(即對象地址),傳遞進(jìn)方法內(nèi),才可以訪問屬性,即才知道訪問哪一個(gè)對象的屬性。這才是方法內(nèi)為什么會(huì)隱含一個(gè)this指針。
  • 靜態(tài)方法:由于靜態(tài)方法內(nèi)不允許含有對象屬性,因此應(yīng)該不含有this指針。這和構(gòu)造方法是不同的,我也一直對《Thinking in Java》所提到的:“構(gòu)造方法應(yīng)該隱含是靜態(tài)的”,持有疑問態(tài)度,雖然某些角度看,兩者有相似的地方,但是從大部分方面看都是不同的。
  • 調(diào)用構(gòu)造方法不一定會(huì)創(chuàng)建對象,但是調(diào)用構(gòu)造方法可以初始化對象。最強(qiáng)有力的證明就是new子類對象的時(shí)候肯定會(huì)調(diào)用父類對象的構(gòu)造方法,但是并不會(huì)創(chuàng)建父類對象。虛擬機(jī)只有接收到new指令的時(shí)候,才會(huì)真正的去創(chuàng)建父類對象。

好了,最后打住收工,啊彌陀否!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容