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