jvm形象简介之一看就懂
分享一波:程序員賺外快-必看的巔峰干貨
據(jù) JVM 規(guī)范,JVM 內(nèi)存結(jié)構(gòu)共分為虛擬機(jī)棧、堆、方法區(qū)、程序計(jì)數(shù)器、本地方法棧五個(gè)部分。這里的java內(nèi)存結(jié)構(gòu)與前面所述的Java內(nèi)存模型是兩個(gè)概念,不可以混淆。
堆
java堆是java虛擬機(jī)所管理的內(nèi)存中最大的一塊,是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。此內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例,這一點(diǎn)在Java虛擬機(jī)規(guī)范中的描述是:所有的對(duì)象實(shí)例以及數(shù)組都要在堆上分配(從這一特性上來(lái)說(shuō),數(shù)組其實(shí)也算是一種對(duì)象)。
java堆是垃圾收集器管理的主要區(qū)域,因此也被成為“GC堆”。從內(nèi)存回收角度來(lái)看java堆可分為:新生代和老生代。從內(nèi)存分配的角度看,線程共享的Java堆中可能劃分出多個(gè)線程私有的分配緩沖區(qū)。無(wú)論怎么劃分,都與存放內(nèi)容無(wú)關(guān),無(wú)論哪個(gè)區(qū)域,存儲(chǔ)的都是對(duì)象實(shí)例,進(jìn)一步的劃分都是為了更好的回收內(nèi)存,或者更快的分配內(nèi)存。
根據(jù)Java虛擬機(jī)規(guī)范的規(guī)定,java堆可以處于物理上不連續(xù)的內(nèi)存空間中。當(dāng)前主流的虛擬機(jī)都是可擴(kuò)展的(通過(guò) -Xmx 和 -Xms 控制)。如果堆中沒(méi)有內(nèi)存完成實(shí)例分配,并且堆也無(wú)法再擴(kuò)展時(shí),將會(huì)拋出OutOfMemoryError異常。
虛擬機(jī)棧
java虛擬機(jī)也是線程私有的,它的生命周期和線程相同。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀(Stack Frame)用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息。
咱們常說(shuō)的堆內(nèi)存、棧內(nèi)存中,棧內(nèi)存指的就是虛擬機(jī)棧。局部變量表存放了編譯期可知的各種基本數(shù)據(jù)類型(8個(gè)基本數(shù)據(jù)類型)、對(duì)象引用(地址指針)、returnAddress類型。
局部變量表所需的內(nèi)存空間在編譯期間完成分配。在運(yùn)行期間不會(huì)改變局部變量表的大小。
這個(gè)區(qū)域規(guī)定了兩種異常狀態(tài):如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度,則拋出StackOverflowError異常;如果虛擬機(jī)??梢詣?dòng)態(tài)擴(kuò)展,在擴(kuò)展是無(wú)法申請(qǐng)到足夠的內(nèi)存,就會(huì)拋出OutOfMemoryError異常。
本地方法棧
本地方法棧與虛擬機(jī)棧所發(fā)揮作用非常相似,它們之間的區(qū)別不過(guò)是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則為虛擬機(jī)使用到的native方法服務(wù)。本地方法棧也是拋出兩個(gè)異常。
方法區(qū)
方法區(qū)與java堆一樣,是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。它有個(gè)別命叫Non-Heap(非堆)。當(dāng)方法區(qū)無(wú)法滿足內(nèi)存分配需求時(shí),拋出OutOfMemoryError異常。
運(yùn)行時(shí)常量池
運(yùn)行時(shí)常量池是方法區(qū)的一部分。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項(xiàng)信息是常量池,用于存放編譯期生成的各種字面量和符號(hào)引用,這部分內(nèi)容將在加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池中存放。
程序計(jì)數(shù)器
程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,它可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。
由于Java虛擬機(jī)的多線程是通過(guò)線程輪流切換并分配處理器執(zhí)行時(shí)間的方式來(lái)實(shí)現(xiàn)的,一個(gè)處理器都只會(huì)執(zhí)行一條線程中的指令。因此,為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程都有一個(gè)獨(dú)立的程序計(jì)數(shù)器,各個(gè)線程之間計(jì)數(shù)器互不影響,獨(dú)立存儲(chǔ)。稱之為“線程私有”的內(nèi)存。程序計(jì)數(shù)器內(nèi)存區(qū)域是虛擬機(jī)中唯一沒(méi)有規(guī)定OutOfMemoryError情況的區(qū)域。
*************************************優(yōu)雅的分割線 **********************************
分享一波:程序員賺外快-必看的巔峰干貨
如果以上內(nèi)容對(duì)你覺(jué)得有用,并想獲取更多的賺錢(qián)方式和免費(fèi)的技術(shù)教程
請(qǐng)關(guān)注微信公眾號(hào):HB荷包
一個(gè)能讓你學(xué)習(xí)技術(shù)和賺錢(qián)方法的公眾號(hào),持續(xù)更新
總結(jié)
以上是生活随笔為你收集整理的jvm形象简介之一看就懂的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: oracle-SQL-case when
- 下一篇: 查看Scala编译的.class文件