Java -----JVM运行时数据区
一、JVM體系結(jié)構(gòu)
想要了解運(yùn)行時(shí)數(shù)據(jù)區(qū),先關(guān)注一下JVM的體系結(jié)構(gòu),知道數(shù)據(jù)區(qū)在JVM的整體位置和作用。
二、JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)
1.程序計(jì)數(shù)器
一塊較小的內(nèi)存空間,它是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器,字節(jié)碼解釋器工作時(shí)通過改變?cè)撚?jì)數(shù)器的值來選擇下一條需要執(zhí)行的字節(jié)碼指令,分支、跳轉(zhuǎn)、循環(huán)等基礎(chǔ)功能都要依賴它來實(shí)現(xiàn)。每條線程都有一個(gè)獨(dú)立的的程序計(jì)數(shù)器,各線程間的計(jì)數(shù)器互不影響,因此該區(qū)域是線程私有的。
??? 當(dāng)線程在執(zhí)行一個(gè)Java方法時(shí),該計(jì)數(shù)器記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址,當(dāng)線程在執(zhí)行的是Native方法(調(diào)用本地操作系統(tǒng)方法)時(shí),該計(jì)數(shù)器的值為空。另外,該內(nèi)存區(qū)域是唯一一個(gè)在Java虛擬機(jī)規(guī)范中沒有規(guī)定任何OOM(內(nèi)存溢出:OutOfMemoryError)情況的區(qū)域。
2.Java虛擬機(jī)棧—JVM Stacks
JVM棧是線程私有的,每個(gè)線程創(chuàng)建的同時(shí)都會(huì)創(chuàng)建JVM棧,java虛擬機(jī)對(duì)Java棧的兩種操作:以幀為單位的壓棧和彈棧。
每當(dāng)線程調(diào)用一個(gè)Java方法是,虛擬機(jī)都會(huì)在該線程的Java棧中亞茹一個(gè)新的棧幀。而這個(gè)棧幀存儲(chǔ)著該方法的參數(shù),局部變量,中間運(yùn)算結(jié)果等等數(shù)據(jù)。
棧幀
由三部分組成:局部變量、操作數(shù)棧和幀數(shù)據(jù)區(qū)
局部變量:包含對(duì)應(yīng)方法的參數(shù)和局部變量,局部變量區(qū)是以字長(zhǎng)為單位存儲(chǔ)數(shù)據(jù)的,并且是一個(gè)從0開始計(jì)數(shù)的數(shù)組空間,數(shù)據(jù)類型int 、float、對(duì)象的引用reference和returnAddress被存儲(chǔ)在一個(gè)存儲(chǔ)空間,而類型byte、short和char的值存入數(shù)組前都會(huì)被轉(zhuǎn)換成int值。一次也是占據(jù)一個(gè)存儲(chǔ)空間,long和double在數(shù)組中占據(jù)連續(xù)的兩個(gè)存儲(chǔ)空間。
??????
可以看到在0的位置會(huì)存儲(chǔ)一個(gè)隱含的變量this,用老表示調(diào)用該方法的對(duì)象本身。
????????
而類方法并沒有this,因?yàn)轭惙椒ㄖ慌c類相關(guān)。而與具體的對(duì)象無關(guān)。
操作數(shù)棧
虛擬機(jī)在操作數(shù)棧中存儲(chǔ)的是方法運(yùn)算的操作數(shù)和運(yùn)算結(jié)果,操作方式是壓棧和出棧,數(shù)據(jù)的存儲(chǔ)方式和上面說的局部變量存儲(chǔ)方式是一樣的。
Java虛擬機(jī)中國(guó)是沒有寄存器的,這也是符合JVM平臺(tái)無關(guān)特性的一點(diǎn),虛擬機(jī)把操作數(shù)棧作為他的工作區(qū),大多數(shù)指令都會(huì)從這里彈出數(shù)據(jù),執(zhí)行運(yùn)算,然后再把結(jié)果壓回操作數(shù)棧
幀數(shù)據(jù)區(qū)
Java棧幀還需要一些數(shù)據(jù)來支持常量池解析、正常方法返回以及異常派發(fā)機(jī)制,這些信息都被保存在Java棧幀的幀數(shù)據(jù)區(qū)中
?
3.本地方法棧(Native Method Stacks)
該區(qū)域與虛擬機(jī)棧所發(fā)揮的作用非常相似,只是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法服務(wù),而本地方法棧則為使用到的本地操作系統(tǒng)(Native)方法服務(wù)。
4.Java堆(Java Heap)
它是JVM用來存儲(chǔ)對(duì)象實(shí)例以及數(shù)組值的區(qū)域,可以認(rèn)為Java中所有通過new創(chuàng)建的對(duì)象的內(nèi)存都在此分配,Heap中的對(duì)象的內(nèi)存需要等待GC進(jìn)行回收。
5.方法區(qū)域(Method Area)
方法區(qū)在JVM中也是一個(gè)非常重要的區(qū)域,它與堆一樣,是被線程共享的區(qū)域。在方法區(qū)中,存儲(chǔ)了每個(gè)類的信息(包括類的名稱、方法信息、字段信息)、靜態(tài)變量、常量以及編譯器編譯后的代碼等。
在Class文件中除了類的字段、方法、接口等描述信息外,還有一項(xiàng)信息是常量池,用來存儲(chǔ)編譯期間生成的字面量和符號(hào)引用。
在方法區(qū)中有一個(gè)非常重要的部分就是運(yùn)行時(shí)常量池,它是每一個(gè)類或接口的常量池的運(yùn)行時(shí)表示形式,在類和接口被加載到JVM后,對(duì)應(yīng)的運(yùn)行時(shí)常量池就被創(chuàng)建出來。當(dāng)然并非Class文件常量池中的內(nèi)容才能進(jìn)入運(yùn)行時(shí)常量池,在運(yùn)行期間也可將新的常量放入運(yùn)行時(shí)常量池中,比如String的intern方法。
在JVM規(guī)范中,沒有強(qiáng)制要求方法區(qū)必須實(shí)現(xiàn)垃圾回收。很多人習(xí)慣將方法區(qū)稱為“永久代”,是因?yàn)镠otSpot虛擬機(jī)以永久代來實(shí)現(xiàn)方法區(qū),從而JVM的垃圾收集器可以像管理堆區(qū)一樣管理這部分區(qū)域,從而不需要專門為這部分設(shè)計(jì)垃圾回收機(jī)制。不過自從JDK7之后,Hotspot虛擬機(jī)便將運(yùn)行時(shí)常量池從永久代移除了。
總結(jié):
轉(zhuǎn)載于:https://www.cnblogs.com/Actexpler-S/p/7668662.html
總結(jié)
以上是生活随笔為你收集整理的Java -----JVM运行时数据区的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网银转账多久到账?国有四大行转账时间一览
- 下一篇: 有银行卡如何开通网银?要收费吗?