1. 程式人生 > >java內存區域的分布

java內存區域的分布

棧幀 ring -type 生成 native 字節碼指令 final 便宜 一個棧

讀了《深入理解Java虛擬機》之後,當時理解了,過段時間又忘記了,在此做下記錄,方便自我回顧,也希望能幫到想要學習虛擬機的同學。

Java虛擬機在執行java程序時會把它所管理的內存分為5個不同的數據區域(也可以細分為7個不同的區域,後續做介紹):程序計數器、Java虛擬機棧、本地方法棧、Java堆、方法區

技術分享

          java虛擬機運行時數據區

  1、程序計數器:用來記錄正在執行的虛擬機字節碼指令地址。可通過改變這個計數器的值來選取下一條需要執行的字節碼指令。

    • 線程私有:為了線程切換後能恢復到正確的位置,每條線程都需要有一個獨立的程序計數器,各條線程之間計數器互不影響。

  2、Java虛擬機棧:線程私有,生命周期與線程相同,每當創建一個線程時,JVM就會為這個線程創建一個對應的java棧。在這個java棧中又會包含多個棧幀,每運行一個方法就創建一個棧幀,用於存儲局部變量表、操作棧、方法返回值等。每一個方法從調用直至執行完成的過程,就對應一個棧幀在java棧中入棧到出棧的過程。

    • 局部變量表:存放編譯器可知的各種基本數據類型、對象引用。

  3、本地方法棧:與虛擬機棧發揮的作用相似,區別在於:虛擬機棧為虛擬機執行java方法(也就是字節碼)服務,本地方法棧為虛擬機使用到的Native方法服務。

  4、java堆:存儲對象實例以及數組。是垃圾收集器管理的主要區域。

    • 線程共享。java堆可以處於物理上不連續的內存空間,只要邏輯上連續即可。

  5、方法區:用於存放類信息(如類名、訪問修飾符等)、常量池、靜態變量、即時編譯器便宜後的代碼等。雖然JVM規範把方法區描述為堆的一個邏輯部分, 但它卻有個別名non-heap(非堆),目的應該是與Java堆區分開來。    

  6、運行時常量池:方法區的一部分,用於存放編譯期生成的各種字面量和符號引用。

    • 常量池:指的是編譯期被確定並被保存在已編譯的.class文件中的一些數據,除了包含代碼中所定義的各種基本類型(如int、long等)和對象類型(如String和數組)的常量值(final),還包含一些以文本形式出現的一些符號引用。

  7、直接內存:堆外的內存。它不是虛擬機運行時數據區的一部分,也不是java虛擬機規範中定義的內存區域。      

java內存區域的分布