各位父老鄉(xiāng)親兄弟姐妹們。周末到了灿渴,講道理今天不應(yīng)該跟大家聊這種索然無味的技術(shù)梗洛波。但是既然開了頭不能虎頭蛇尾的。也到了這個(gè)系列的最后一塊——方法區(qū)骚露。昨天我們也預(yù)告了蹬挤,那既然放出話了就肯定要把諾言實(shí)現(xiàn)。我們今天就把這個(gè)系列給完結(jié)了棘幸。今天我們來聊聊JVM中的方法區(qū)(Method Area)焰扳。
方法區(qū)概述
我們用幾個(gè)點(diǎn)來概括一下方法區(qū)是個(gè)什么東西和有什么用途。
方法區(qū)跟昨天介紹的堆都是各線程共享的內(nèi)存區(qū)域误续。方法區(qū)主要是存儲(chǔ)已經(jīng)被虛擬機(jī)加載的類信息因惭、常量环疼、靜態(tài)變量暂衡、即時(shí)編譯器編譯后的代碼和數(shù)據(jù)青自。
Java虛擬機(jī)中也有把方法區(qū)描述為堆的一個(gè)邏輯部分,但是它有一個(gè)別名叫做Non-Heap【非堆】栽烂,目的就是與Java堆區(qū)分開來躏仇。
對(duì)HotSpot虛擬機(jī)開發(fā)者來說,方法區(qū)也稱為是永久代(Permanent Generation),其實(shí)在本質(zhì)上二者不等價(jià)腺办,僅僅是因?yàn)镠otSpot的團(tuán)隊(duì)把GC分代收集擴(kuò)展至方法區(qū)焰手,或者說使用永久代來實(shí)現(xiàn)方法區(qū)。節(jié)省了專門為方法區(qū)編寫內(nèi)存管理代碼的工作菇晃。
對(duì)于其他虛擬機(jī)(BEA JRockit册倒、IBM J9等)來說是不存在永久代的概念。
使用永久代來實(shí)現(xiàn)方法區(qū)更容易出現(xiàn)內(nèi)存溢出問題(永久代有-XX:MaxPermSize的上限,J9和JRockit只要沒有觸碰到進(jìn)程可用的內(nèi)存上限就不會(huì)出現(xiàn)問題)磺送。
當(dāng)方法區(qū)無法滿足內(nèi)存分配的需求時(shí)驻子,將拋出OutOfMemoryError異常,這時(shí)候你的程序一般也就掛了估灿。
Java虛擬機(jī)規(guī)范對(duì)于方法區(qū)的限制非常寬松崇呵。只要滿足下面的三個(gè)條件即可:
不需要連續(xù)內(nèi)存
可選擇固定大小或者可擴(kuò)展
不實(shí)現(xiàn)垃圾收集
運(yùn)行時(shí)常量池(Runtime Constant Pool)
運(yùn)行時(shí)常量池是方法區(qū)的一部分。用于存放編譯期生成的各種字面量和符號(hào)引用馅袁,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池域慷。
Java虛擬機(jī)對(duì)于Class文件的每一部分的格式都有嚴(yán)格規(guī)定,但是對(duì)于運(yùn)行時(shí)常量池Java虛擬機(jī)規(guī)范沒有做出任何細(xì)節(jié)的要求。
一般來說犹褒,除了保存Class文件中描述的符號(hào)引用外抵窒,還會(huì)把翻譯出來的直接引用也存儲(chǔ)在運(yùn)行時(shí)常量池。
運(yùn)行時(shí)常量池相對(duì)于Class文件常量池的另一個(gè)重要的特征是動(dòng)態(tài)性叠骑。運(yùn)行期間也可能將新的常亮放到池中李皇。
運(yùn)行時(shí)常量池是方法區(qū)的一部分。也會(huì)出現(xiàn)OutOfMemoryError宙枷。
到這里我們關(guān)于JVM的所有區(qū)域介紹都已經(jīng)說完了掉房。下面我們把剩下的最后的一個(gè)跟JVM虛擬機(jī)有類似的功能。也是大家經(jīng)常見到的區(qū)塊——直接內(nèi)存慰丛。嚴(yán)格意義上來說直接內(nèi)存跟JVM無關(guān)卓囚。但是我們還是提一提吧。在特定的功能下還是很有了解的必要的诅病。
直接內(nèi)存(Direct Memory)
直接內(nèi)存并不是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分哪亿。也不是Java虛擬機(jī)規(guī)范中定義的內(nèi)存區(qū)域。
JDK1.4新加入的NIO類贤笆,引入了基于通道(Channel)與緩沖區(qū)(Buffer)的I/O方式锣夹。它可以使用Native函數(shù)庫直接分配堆外內(nèi)存。然后通過一個(gè)存儲(chǔ)在Java堆中的DirectByteBuffer對(duì)象作為這塊內(nèi)存的引用進(jìn)行操作苏潜。
直接內(nèi)存的分配不會(huì)受到Java堆大小的限制。但是會(huì)受到本機(jī)總內(nèi)存大小以及處理器尋址空間的限制变勇。
到這里我們所有的關(guān)于JVM的介紹都已經(jīng)說完了恤左。這周的工作時(shí)間內(nèi)都在總結(jié)這幾塊的關(guān)系。后面我們會(huì)對(duì)各種工作中遇到的問題總結(jié)出來分享給大家搀绣。希望大家別踩我踩過的坑飞袋。也祝大家周末愉快。
我的文章每天都會(huì)在頭條號(hào)首發(fā)链患,然后第二天轉(zhuǎn)發(fā)到簡書中巧鸭,希望有興趣的朋友可以關(guān)注我的頭條號(hào):[Bug制造機(jī)]
(https://www.toutiao.com/c/user/51553105950/#mid=1582105392193550)。謝謝大家的支持麻捻。