jvm有哪些内存区域
1、程序計數器
程序計數器是一塊很小的內存空間,它是線程私有的,可以認作為當前線程的行號指示器。
那么計數器記錄虛擬機字節碼指令的地址。如果為native【底層方法】,那么計數器為空。
這塊內存區域是虛擬機規范中唯一沒有OutOfMemoryError的區域。
2、Java棧(虛擬機棧)
棧描述的是Java方法執行的內存模型。
每個方法被執行的時候都會創建一個棧幀用于存儲局部變量表,操作棧,動態鏈接,方法出口等信息。每一個方法被調用的過程就對應一個棧幀在虛擬機棧中從入棧到出棧的過程。
平時說的棧一般指局部變量表部分。
局部變量表所需要的內存空間在編譯期完成分配,當進入一個方法時,這個方法在棧中需要分配多大的局部變量空間是完全確定的,在方法運行期間不會改變局部變量表大小。
Java虛擬機棧可能出現兩種類型的異常:
線程請求的棧深度大于虛擬機允許的棧深度,將拋出StackOverflowError。
虛擬機棧空間可以動態擴展,當動態擴展是無法申請到足夠的空間時,拋出OutOfMemory異常
3、本地方法棧
本地方法棧是與虛擬機棧發揮的作用十分相似,區別是虛擬機棧執行的是Java方法(也就是字節碼)服務,而本地方法棧則為虛擬機使用到的native方法服務,可能底層調用的c或者c++,我們打開jdk安裝目錄可以看到也有很多用c編寫的文件,可能就是native方法所調用的c代碼。
4、堆
堆是java虛擬機管理內存最大的一塊內存區域,因為堆存放的對象是線程共享的,所以多線程的時候也需要同步機制。
java虛擬機規范對這塊的描述是:所有對象實例及數組都要在堆上分配內存,但隨著JIT編譯器的發展和逃逸分析技術的成熟,這個說法也不是那么絕對,但是大多數情況都是這樣的。
即時編譯器:可以把把Java的字節碼,包括需要被解釋的指令的程序)轉換成可以直接發送給處理器的指令的程序)
逃逸分析:通過逃逸分析來決定某些實例或者變量是否要在堆中進行分配,如果開啟了逃逸分析,即可將這些變量直接在棧上進行分配,而非堆上進行分配。這些變量的指針可以被全局所引用,或者其其它線程所引用。
堆是所有線程共享的,它的目的是存放對象實例。同時它也是GC所管理的主要區域,因此常被稱為GC堆,又由于現在收集器常使用分代算法,Java堆中還可以細分為新生代和老年代。
根據虛擬機規范,Java堆可以存在物理上不連續的內存空間,就像磁盤空間只要邏輯是連續的即可。它的內存大小可以設為固定大小,也可以擴展。
當前主流的虛擬機如HotPot都能按擴展實現(通過設置 -Xmx和-Xms),如果堆中沒有內存內存完成實例分配,而且堆無法擴展將報OOM錯誤(OutOfMemoryError)
5、元空間
元空間同堆一樣,是所有線程共享的內存區域,為了區分堆,又被稱為非堆。
元空間用于存儲已被虛擬機加載的類信息、常量、靜態變量,如static修飾的變量加載類的時候就被加載到方法區中。
在老版jdk,元空間也被稱為永久代、方法區。
總結
以上是生活随笔為你收集整理的jvm有哪些内存区域的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 堆空间大小怎么配置,各区域怎么划分
- 下一篇: jvm可以运行多种语言吗