Java中的堆、棧、方法區、運行時常量池的簡單介紹

在上次咱們簡單介紹了Java的反射機制,在學習Java的反射的時候,咱們有一張Java內存的模型圖,以下:java

如今咱們來簡單講講這個內存模型圖中的堆、棧、方法區吧!程序員

        棧(stack)與堆(heap)都是Java用來在RAM中存放數據的地方。與C++不一樣,Java自動管理棧和堆,程序員不能直接地設置棧或堆。 數組

Java棧:函數

      每一條 Java 虛擬機線程都有本身私有的 Java 虛擬機棧(Java Virtual Machine Stack),這個棧與線程同時建立,用於存儲棧幀。Java 虛擬機棧的做用與傳統語 言(例如 C 語言)中的棧很是相似,就是用於存儲局部變量與一些過程結果的地方。另外,它在 方法調用和返回中也扮演了很重要的角色。由於除了棧幀的出棧和入棧以外,Java 虛擬機棧不會再受其餘因素的影響,因此棧幀能夠在堆中分配,Java 虛擬機棧所使用的內存不須要保證是連續的。學習

      在函數中定義的一些基本類型的變量和對象的引用變量都是在函數的棧內存中分配。當在一段代碼塊中定義一個變量時,java就在棧中爲這個變量分配內存空間,當超過變量的做用域後,java會自動釋放掉爲該變量分配的內存空間,該內存空間能夠馬上被另做他用。線程

Java堆:對象

        在Java虛擬機中,堆(Heap)是可供各條線程共享的運行時內存區域,也是供全部類實例和數組對象分配內存的區域。Java 堆在虛擬機啓動的時候就被建立,它裏面存儲了被自動內存管理系統(即咱們常說的垃圾回收器)所管理的各類對象。Java 堆的容量能夠是固定大小的,也能夠隨着程序執行的需求動態擴展,並在不須要過多空間時自動收縮。Java 堆所使用的內存不須要保證是連續的。接口

方法區:內存

        在Java虛擬機中,方法區(Method Area)是可供各條線程共享的運行時內存區域。它存儲了每個類的結構信息,例如運行時常量池、字段和方法數據、構造函數和普通方法的字節碼內容、還包括一些在類、實例、接口初始化時用到的特殊方法。方法區的容量能夠是固定大小的,也能夠隨着程序執行的需求動態擴展,並在不須要過多空間時自動收縮。方法區在實際內存空間中能夠是不連續的。作用域

運行時常量池:

       運行時常量池(Runtime Constant Pool)是每個類或接口的常量池的運行時表示形式,它包括了若干種不一樣的常量:從編譯期可知的數值字面量到必須運行解析後才能得到的方法或字段引用。運行時常量池扮演了相似傳統語言中符號表的角色,不過它存儲數據範圍比一般意義上的符號表要更爲普遍。每個運行時常量池都分配在 Java 虛擬機的方法區之中,在類和接口被加載到虛擬機後,對應的運行時常量池就被建立出來。

        從堆和棧的功能和做用來通俗的比較,堆主要用來存放對象的,棧主要是用來執行程序的。堆內存用來存放由new建立的對象和數組,在堆中分配的內存,由JVM的自動垃圾回收器來管理。而棧的優點是,存取速度比堆要快,僅次於寄存器。棧數據能夠共享。但缺點是,存在棧中的數據大小與生存期必須是肯定的,缺少靈活性。棧中主要存放一些基本類型的變量(,int, short, long, byte, float, double, boolean, char)和對象句柄。 

異常狀況:

    若是線程請求分配的棧容量超過 Java 虛擬機棧容許的最大容量時,Java 虛擬機將會拋出一 個 StackOverflowError 異常。    

    若是 Java 虛擬機棧能夠動態擴展,而且擴展的動做已經嘗試過,可是目前沒法申請到足夠的內存去完成擴展,或者在創建新的線程時沒有足夠的內存去建立對應的虛擬機棧,那Java 虛擬機將會拋出一個 OutOfMemoryError 異常。

    若是實際所需的堆超過了自動內存管理系統能提供的最大容量,那Java 虛擬機將會拋出一個 OutOfMemoryError 異常。

    若是方法區的內存空間不能知足內存分配請求,那 Java 虛擬機將拋出一個OutOfMemoryError 異常。

    當建立類或接口的時候,若是構造運行時常量池所須要的內存空間超過了方法區所能提供的最大值,那 Java 虛擬機將會拋出一個OutOfMemoryError 異常。

        最後,我感受知識越學越深,理解一個概念的同時,要知道好幾個概念才能明白這個概念。也許這就是驅動本身學習的一個方法吧!

相關文章
相關標籤/搜索