Java知識學習——方法區(一)

什麼是方法區?

前面瞭解了JVM內存結構中的程序計數器、虛擬機棧、本地方法棧和堆之後,還有最後一個內存結構——方法區。

方法區從名字上看與我們類的方法有關,確實如此,但是還不是很完整的概括,對於方法區的定義各有千秋,但在JVM規範中是這樣定義的。

從其定義,首先可以得到,方法區是所有線程共享的區域。其次,在方法區中存放了跟類結構的相關信息(運行時常量池),包括成員變量、方法數據,成員方法以及構造方法的代碼部分。

方法區在虛擬機啓動的時候創建,它在邏輯上是堆的一個組成部分。方法區只是一個概念,並不是一個具體的實現,對於方法區具體內容如下圖:

在JDK1.6中,方法區的實現使用了一個永久代實現,在永久代中可以存儲類的信息、類加載器還有一塊就是運行時常量池,在常量池有一個非常重要的一個串池——StringTable。在1.8中方法區用永久代的實現方式被廢棄,改爲由一個元空間的來實現,同樣在元空間包含了類信息、類加載器、常量池,這個時候方法區已經不佔用堆內存,換句話說此時方法區就不是由JVM來管理它的內存結構,它已經移出到本地內存中,所謂本地內存就是操作系統的內存,在1.8中StringTable已經不是在方法區,而是在堆中。

方法區的內存溢出問題

方法區就是來存儲類的結構數據,當類加載過多時,就會出現OutOfMemoryError的,即內存溢出。在1.8版本因爲元空間是直接使用的操作系統內存,而操作系統的內存現在一般是4G、8G、16G,所以出現內存溢出是很少的,但是如果設置虛擬機的參數:-XX:MaxMetaspacesize+大小,就可以模擬出內存溢出的問題。在1.8以前也是受永久代的空間大小會出現內存溢出的問題,同樣可以通過設置虛擬機參數:-XX:MaxPermSize+大小也可以模擬出內存溢出的問題。

通過類加載模擬元空間內存溢出

如今,我們常用的框架Spring、Mybatis這些框架都會大量的在運行時生成類,在1.8之前很容易導致永久代空間不足,在1.8之後由於元空間使用的是系統內存,相對而言充裕了很多,並且垃圾回收機制也是由元空間自行管理,不會像永久代垃圾回收效率比較低。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章