深入理解JAVA虛擬機-JAVA內存區域

運行時數據區域

  對象的創建與訪問定位

  1. 堆和方法區:都是爲了共享資源而設計,邏輯上是等價的。但是方法區更側重於保存"結構":存儲運行時常量池,class信息,靜態變量等,這些結構是更難解析,更難回收,並非GC的主要目標,可以用永久代實現。 而堆更側重保存"數據元":存放對象Instance,物理上並非連續,可以動態擴展,但不可超出可分配內存,否則OOM,是GC的主要目標,在堆內對Instance進行分代,以便更好的回收。簡單的說:方法區是一個個class、堆上是這些class new出來的一個個對象
  2. Java虛擬機棧:線程私有,與線程同生命週期,這也就意味着N個線程存在N個棧,每個棧首先要有PC,即決定當前是哪個線程在執行,下一個pc地址代表哪個線程將會被執行。在每個線程棧中會依次入棧當前方法、當前對象、當前變量等。當請求的棧超過物理深度時會報StackOverflowError。
  3. 虛擬機棧-變量彈棧:執行變量 x 和存取地址(store load addr)
  4. 虛擬機棧-方法:A調用return的方法B時,A入棧,調用B,return_B入棧,操作B,return_B彈棧,A彈棧
  5. 對象創建:以Person zhangsan = new Person()爲例,分爲兩步,可以當成編譯器在掃描時將Person zhangsan =入棧,然後將new Person()入棧;步驟一,彈棧,取出new Person(),new是一個申請內存的指令,依次會通過類型檢查,分配全爲默認值的內存空間(除了對象頭,此時對象頭部已經存在)。步驟二,彈棧,取出Person zhangsan = ,對步驟一new出來的內存空間用zhangsan的name,age等屬性進行初始化
  6. 對象的訪問定位:zhangsan的引用彈棧,引用中存放的是堆中zhangsan的地址(reference = C++中指針),而堆中zhangsan的對象頭Object Header中存放了方法區的Person.class的地址(反射?)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章