Java虛擬機器

來源:互聯網
上載者:User

標籤:模型   rom   除了   回收   卸載   runtime   werror   output   double   

Java記憶體地區運行時資料區域

程式計數器(Program Counter Register)

  • 較小的記憶體空間,是當前線程執行的位元組碼的行號的指標。位元組碼解譯器通過改變計數器的值來擷取下一條位元組碼指令,分支、迴圈、跳轉、異常處理、線程恢複都靠它完成.
  • 每個線程都有自己的一個計數器,線程之間計數器互不影響.
  • 執行Native方法時,計數器不起作用,值為空白(Undefined)。
  • 此地區是唯一沒有規定OOM的地區.

Java虛擬機器棧 Java Virtual Machine Stack

  • 歸屬線程所有,生命週期與歸屬的線程相同。
  • 虛擬機器棧描述的是Java方法執行的記憶體模型:
    • 方法執行時會建立棧幀(Stack Frame)儲存局部變數表、運算元棧、動態連結、方法出口等.
    • 方法的調用到執行完成的過程,對應其棧幀從虛擬機器棧中入棧到出棧的過程.
  • 局部變數表存放編譯器可知的基礎資料型別 (Elementary Data Type)、對象引用;long、double因為長度為64bit,會佔用兩個Slot,其他則佔用一個,由此可知局部變數表的記憶體空間在編譯期就完成了分配,方法運行時不改變其大小。
  • 虛擬機器棧中規定的兩種異常情況:
    • StackOverflowError:線程請求的棧深度大於虛擬機器所允許的深度.
    • OutOfMemoryError:虛擬機器棧動態擴充記憶體時,無法申請到足夠的記憶體.

本地方法棧 Native Method Stack

  • 類似於虛擬機器棧,區別是虛擬機器棧為虛擬機器執行Java方法服務,而本地方法棧為Native方法工作;Native方法指Java調用的C/C++語言的函數.
  • 本地方法棧地區也會拋出StackOverFlowError & OutOfMemoryError異常。

Java堆 Java Heap

  • JVM中記憶體最大的一塊,所有線程共用,在虛擬機器啟動時建立。幾乎所有對象執行個體、數組都在這裡誕生。
  • Java堆是記憶體回收的主要區域,又稱GC(Garbage Collected Heap)堆。
  • 當堆中沒有記憶體配置執行個體,並且無法擴充時,拋出OOM異常。
  • Java堆可以處於物理上的不連續的記憶體空間中,只要邏輯上是連續的即可。

  • 堆空間的記憶體細分

    • Young Generation:新生代,包含了Eden、S0(FromSurvivor)、S1(ToSurvivor);由於新生代上的對象存活時間很短暫,所以此區一般採用標記-清理演算法GC.
    • Old Generation:老年代,經過多次GC後仍然存活的對象(每個對象都有一個對象年齡計數器),此地區採用一般採用複製演算法GC;大對象,如數組,直接進入老年代.
    • Permanent:永久代,存放不變對象,類、方法、字串等,見以下方法區。
  • 堆記憶體的分代回收
    1. 大多數剛建立的對象會被分配在Eden區,其中的大多數對象很快就會消亡。Eden區是連續的記憶體空間,因此在其上分配記憶體極快.
    2. 當Eden區滿的時候,執行Minor GC,將消亡的對象清理掉,並將剩餘的對象複製到一個存活區Survivor0(此時,Survivor1是空白的,兩個Survivor總有一個是空白的).
    3. 此後,每次Eden區滿了,就執行一次Minor GC,並將剩餘的對象都添加到Survivor0.
    4. 當Survivor0也滿的時候,將其中仍然活著的對象直接複製到Survivor1,以後Eden區執行Minor GC後,就將剩餘的對象添加Survivor1(此時,Survivor0是空白的).
    5. 當兩個存活區切換了幾次(HotSpot虛擬機器預設15次,用-XX:MaxTenuringThreshold控制,大於該值進入老年代)之後,仍然存活的對象(其實只有一小部分,比如,我們自己定義的對象),將被複製到老年代.
    6. 總結:Eden區是連續的空間,且Survivor總有一個為空白;經過一次GC和複製,一個Survivor中儲存著當前還活 著的對象,而Eden區和另一個Survivor區的內容都不再需要了,可以直接清空,到下一次GC時,兩個Survivor的角色再互換。因此,這種方 式分配記憶體和清理記憶體的效率都極高,這種記憶體回收的方式就是著名的“停止-複製(Stop-and-copy)”清理法(將Eden區和一個Survivor中仍然存活的對象拷貝到另一個Survivor中).

方法區 Method Area

  • 所有線程共用,別名No-Heap(非堆)用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的代碼等資料。也叫Permanent Generation(永久代);之所以名為永久代,是因為HotSpot將GC從堆延伸至了方法區。(對於其他虛擬機器IBM J9等來說是不存在永久代的概念的)
  • 與Java堆一樣,是各個線程共用的記憶體地區,它用於儲存 已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的代碼等資料
  • 並非被稱為永久代,其中的資料就永久了,當類型卸載、常量池回收時也會發生GC,但是比較少見。
  • 當此區無法分配新記憶體時,拋出OOM異常。

運行時常量池 Runtime Constant Pool

  • 屬於方法區的一部分,Class檔案中除了有類的版本、欄位、方法、介面等描述資訊外,還有一項資訊是常量池(Constant Pool Table),用於存放編譯期產生的各種字面量和符號引用,這部分內容將在類載入後進入方法區的運行時常量池中存放。
  • 無法申請到記憶體時,拋出OOM異常.

直接記憶體

  • 直接記憶體不是JVM運行時的一部分,但是Java可以通過NIO(New Input/Output),引入Channel和Buffer的I/O方式,它可以用native方法申請堆外記憶體,然後通過JVM堆中的DirectByteBuffer對象操作這塊記憶體,此時申請記憶體是通過Unsafe.allocateMemory方法實現的.

對象訪問

  • 控制代碼訪問方式:Java堆中分配一塊記憶體作為控制代碼池,reference中儲存物件的控制代碼地址,控制代碼中則包含執行個體資料指標和類型資料指標;此方式的好處在於控制代碼地址穩定,對象變動時,只需修改控制代碼,而reference不需改動.
  • 直接指標訪問方式:Java堆對象中存放訪問類型資料資訊,reference直接儲存物件地址;這種做法的好處是速度快,節省了一次指標定位的開銷.

Java虛擬機器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.