詳解Java虛擬機(jī)管理的內(nèi)存運(yùn)行時(shí)數(shù)據(jù)區(qū)域
詳解Java虛擬機(jī)管理的內(nèi)存運(yùn)行時(shí)數(shù)據(jù)區(qū)域
概述
Java虛擬機(jī)在執(zhí)行Java程序的過(guò)程中會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同數(shù)據(jù)區(qū)域。這些區(qū)域都有各自的用途,以及創(chuàng)建和銷(xiāo)毀的時(shí)間,有的區(qū)域隨著虛擬機(jī)進(jìn)程的啟動(dòng)而存在,有些區(qū)域則是依賴用戶線程的啟動(dòng)和結(jié)束而建立和銷(xiāo)毀。

程序計(jì)數(shù)器
程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,它可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。在虛擬機(jī)的概念模型里,字節(jié)碼解釋器工作時(shí)就是通過(guò)改變這個(gè)計(jì)數(shù)器的值來(lái)選取下一條需要執(zhí)行的字節(jié)碼指令,分支,循環(huán),跳轉(zhuǎn),異常處理,線程恢復(fù)等基礎(chǔ)功能都需要依賴這個(gè)計(jì)數(shù)器來(lái)完成。
如果線程正在執(zhí)行的是一個(gè)Java方法,這個(gè)計(jì)數(shù)器記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址,如果正在執(zhí)行的是Native方法,這個(gè)計(jì)數(shù)器值則為空。此內(nèi)存區(qū)域是唯一個(gè)在Java虛擬機(jī)規(guī)范中沒(méi)有規(guī)定任何OurOfMemoryError情況的區(qū)域。
虛擬機(jī)棧
與程序計(jì)數(shù)器一樣,Java虛擬機(jī)棧也是線程私有的,它的生命周期與線程相同。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型,每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀(Stack Frame)用于存儲(chǔ)局部變量表,操作數(shù)棧,動(dòng)態(tài)鏈接,方法出口等信息。每一個(gè)方法從調(diào)用直至執(zhí)行完成的過(guò)程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中入棧到出棧的過(guò)程。
局部變量表存放了編譯期可知的各種基本數(shù)據(jù)類(lèi)型(boolean、byte、char、short、int、float、long、double)、對(duì)象引用(Object reference)和字節(jié)碼指令地址(returnAddress類(lèi)型)。
在Java虛擬機(jī)規(guī)范中,對(duì)于此區(qū)域規(guī)定了兩種異常狀況:如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度,將拋出StackOverflowError異常;如果虛擬機(jī)棧可以動(dòng)態(tài)擴(kuò)展,當(dāng)擴(kuò)展時(shí)無(wú)法申請(qǐng)到足夠的內(nèi)存時(shí)會(huì)拋出OutOfMemoryError異常。
對(duì)于32位的jvm,默認(rèn)大小為256kb, 而64位的jvm, 默認(rèn)大小為512kb,可以通過(guò)-Xss設(shè)置虛擬機(jī)棧的最大值。不過(guò)如果設(shè)置過(guò)大,會(huì)影響到可創(chuàng)建的線程數(shù)量。
方法區(qū)
方法區(qū)與Java堆一樣,是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被虛擬機(jī)加載的類(lèi)信息,常量,靜態(tài)變量,即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。
根據(jù)Java虛擬機(jī)規(guī)范的規(guī)定,當(dāng)方法區(qū)無(wú)法滿足內(nèi)存分配需求時(shí),將拋出OutOfMemoryError異常。
本地方法棧
本地方法棧(Native Method Stacks)與虛擬機(jī)棧所發(fā)揮的作用非常類(lèi)似,區(qū)別在于虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法服務(wù),而本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)。
Java堆
Java堆(java heap)是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊,它是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建,此內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例,幾乎所有的對(duì)象實(shí)例都在這里分配內(nèi)存。
Java堆是垃圾收集管理的主要區(qū)域,因此很多時(shí)候也被稱為 "GC" 堆。
根據(jù)Java虛擬機(jī)規(guī)范的規(guī)定,Java堆可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上是連續(xù)的即可,就像我們的磁盤(pán)空間一樣。在實(shí)現(xiàn)時(shí),既可以實(shí)現(xiàn)成固定大小的,也可以是可擴(kuò)展的,不過(guò)當(dāng)前主流的虛擬機(jī)都是按照可擴(kuò)展來(lái)實(shí)現(xiàn)的。(通過(guò)-Xmx和-Xms控制)如果在堆中沒(méi)有內(nèi)存完成實(shí)例分配,并且堆也無(wú)法再擴(kuò)展時(shí),將會(huì)拋出OutOfMemoryError異常。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Java SpringBoot安全框架整合Spring Security詳解
這篇文章主要介紹了Spring Boot整合Spring Security的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-09-09
Java SpringBoot集成ChatGPT實(shí)現(xiàn)AI聊天
ChatGPT已經(jīng)組件放開(kāi)了,現(xiàn)在都可以基于它寫(xiě)插件了,也許可以用它結(jié)合文字語(yǔ)音開(kāi)發(fā)一個(gè)老人小孩需要的智能的說(shuō)話陪伴啥的,這篇文章就介紹SpringBoot結(jié)合ChatGPT實(shí)現(xiàn)AI聊天感興趣的同學(xué)可以借鑒一下2023-04-04
基于Restful接口調(diào)用方法總結(jié)(超詳細(xì))
下面小編就為大家?guī)?lái)一篇基于Restful接口調(diào)用方法總結(jié)(超詳細(xì))。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
java 定義長(zhǎng)度為0的數(shù)組/空數(shù)組案例
這篇文章主要介紹了java 定義長(zhǎng)度為0的數(shù)組/空數(shù)組案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03
空指針HttpSession異常之SpringBoot集成WebSocket的方法
文章介紹了在Spring?Boot中集成WebSocket時(shí)遇到的HttpSession為空的問(wèn)題,并探討了三種解決方法,方法一涉及域名配置,方法二通過(guò)監(jiān)聽(tīng)創(chuàng)建Session,而方法三是從request中獲取session并存入數(shù)據(jù),感興趣的朋友一起看看吧2025-01-01
Java將GeoHash轉(zhuǎn)化為對(duì)應(yīng)的經(jīng)緯度坐標(biāo)實(shí)例代碼
這篇文章主要介紹了Java實(shí)現(xiàn)將GeoHash轉(zhuǎn)化為對(duì)應(yīng)的經(jīng)緯度坐標(biāo)的相關(guān)資料,需要的朋友可以參考下2016-01-01
Java中synchronized關(guān)鍵字的使用和原理詳解
這篇文章主要介紹了Java中synchronized關(guān)鍵字的使用和原理詳解,JVM 是通過(guò)進(jìn)入、退出 對(duì)象監(jiān)視器(Monitor)來(lái)實(shí)現(xiàn)對(duì)方法、同步塊的同步的,而對(duì)象監(jiān)視器的本質(zhì)依賴于底層操作系統(tǒng)的互斥鎖實(shí)現(xiàn),需要的朋友可以參考下2023-09-09

