Java面試必備之Java虛擬機方法區

各位父老鄉親兄弟姐妹們。周末到了,講道理今天不應該跟大家聊這種索然無味的技術梗。但是既然開了頭不能虎頭蛇尾的。也到了這個系列的最后一塊——方法區。昨天我們也預告了,那既然放出話了就肯定要把諾言實現。我們今天就把這個系列給完結了。今天我們來聊聊JVM中的方法區(Method Area)。

Java面試必備之Java虛擬機方法區

方法區概述

我們用幾個點來概括一下方法區是個什么東西和有什么用途。
方法區跟昨天介紹的堆都是各線程共享的內存區域。方法區主要是存儲已經被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼和數據。

Java虛擬機中也有把方法區描述為堆的一個邏輯部分,但是它有一個別名叫做Non-Heap【非堆】,目的就是與Java堆區分開來。

對HotSpot虛擬機開發者來說,方法區也稱為是永久代(Permanent Generation),其實在本質上二者不等價,僅僅是因為HotSpot的團隊把GC分代收集擴展至方法區,或者說使用永久代來實現方法區。節省了專門為方法區編寫內存管理代碼的工作。

對于其他虛擬機(BEA JRockit、IBM J9等)來說是不存在永久代的概念。

使用永久代來實現方法區更容易出現內存溢出問題(永久代有-XX:MaxPermSize的上限,J9和JRockit只要沒有觸碰到進程可用的內存上限就不會出現問題)。

當方法區無法滿足內存分配的需求時,將拋出OutOfMemoryError異常,這時候你的程序一般也就掛了。

Java虛擬機規范對于方法區的限制非常寬松。只要滿足下面的三個條件即可:

不需要連續內存

可選擇固定大小或者可擴展

不實現垃圾收集

運行時常量池(Runtime Constant Pool)

運行時常量池是方法區的一部分。用于存放編譯期生成的各種字面量和符號引用,這部分內容將在類加載后進入方法區的運行時常量池。

Java虛擬機對于Class文件的每一部分的格式都有嚴格規定,但是對于運行時常量池Java虛擬機規范沒有做出任何細節的要求。

一般來說,除了保存Class文件中描述的符號引用外,還會把翻譯出來的直接引用也存儲在運行時常量池。

運行時常量池相對于Class文件常量池的另一個重要的特征是動態性。運行期間也可能將新的常亮放到池中。

運行時常量池是方法區的一部分。也會出現OutOfMemoryError。

到這里我們關于JVM的所有區域介紹都已經說完了。下面我們把剩下的最后的一個跟JVM虛擬機有類似的功能。也是大家經常見到的區塊——直接內存。嚴格意義上來說直接內存跟JVM無關。但是我們還是提一提吧。在特定的功能下還是很有了解的必要的。
直接內存(Direct Memory)
直接內存并不是虛擬機運行時數據區的一部分。也不是Java虛擬機規范中定義的內存區域。

JDK1.4新加入的NIO類,引入了基于通道(Channel)與緩沖區(Buffer)的I/O方式。它可以使用Native函數庫直接分配堆外內存。然后通過一個存儲在Java堆中的DirectByteBuffer對象作為這塊內存的引用進行操作。

直接內存的分配不會受到Java堆大小的限制。但是會受到本機總內存大小以及處理器尋址空間的限制。

到這里我們所有的關于JVM的介紹都已經說完了。這周的工作時間內都在總結這幾塊的關系。后面我們會對各種工作中遇到的問題總結出來分享給大家。希望大家別踩我踩過的坑。也祝大家周末愉快。
我的文章每天都會在頭條號首發,然后第二天轉發到簡書中,希望有興趣的朋友可以關注我的頭條號:[Bug制造機]
(https://www.toutiao.com/c/user/51553105950/#mid=1582105392193550)。謝謝大家的支持。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容