定義
所有java 虛擬機線程共享的一塊區(qū)域,存儲了所有類相關信息,在虛擬機啟動時被創(chuàng)建,JVM關閉就會釋放方法區(qū)的空間。不同版本實現(xiàn)方式不同。例如永久代,元空間。
JDK1.6及之前:永久代。靜態(tài)變量在永久代中
JDK1.7 :永久代。字符串常量池、靜態(tài)變量移除,放入堆中。
JDK1.8及之后的實現(xiàn)方式:元空間。不在虛擬機設置的內(nèi)存中,而是使用本地內(nèi)存。類信息、字段、方法、常量保存在本地內(nèi)存,但字符串常量池、靜態(tài)變量仍在堆中。
方法區(qū)的內(nèi)部結(jié)構
類的信息、屬性、方法、異常表等。其中有他們的全類名,返回類型,權限修飾符等
從字節(jié)碼文件看
從字節(jié)碼文件看
被final修飾的屬性在編譯的時候就賦值了。
從字節(jié)碼來看
方法區(qū)內(nèi)存溢出
類加載的個數(shù)過多
1. 1.8以前會導致永久代內(nèi)存溢出(使用MaxPermSize設置永久代大小)
2.?1.8以后會導致元空間內(nèi)存溢出(使用系統(tǒng)內(nèi)存,可以使用MaxMetaSpace設置元空間大小)
溢出場景
加載大量的第三方的jar包:Tomcat部署的工程過多(30-50個):大量動態(tài)的生成反射類
?實際場景中spring,mybatis:會產(chǎn)生大量的動態(tài)生成類
演示溢出
設置方法區(qū)內(nèi)存大小
JDK 7 以前:
-XX:PermSize=100m
-XX:MaxPermSize=100m
JDK8及以后:
-XX:MetaspaceSize=100m
-XX:MaxMetaspaceSize=100m
如何解決OOM
方法區(qū)可以有垃圾回收也可以沒有,方法區(qū)的垃圾收集主要回收兩部分內(nèi)容:常量池中廢棄的常量和不再使用的類型。