Java虛擬機(jī)規(guī)范中只定義了方法區(qū)用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量和即時(shí)編譯后的代碼等數(shù)據(jù)。
1、jdk1.7開始符號(hào)引用存儲(chǔ)在native heap中,字符串常量和靜態(tài)類型變量存儲(chǔ)在普通的堆區(qū)中,但分離的并不徹底,此時(shí)永久代中還保存另一些與類的元數(shù)據(jù)無(wú)關(guān)的雜項(xiàng);
2、jdk8后HotSpot 原永久代中存儲(chǔ)的類的元數(shù)據(jù)將存儲(chǔ)在metaspace中,而類的靜態(tài)變量和字符串常量將放在Java堆中,metaspace是方法區(qū)的一種實(shí)現(xiàn),只不過(guò)它使用的不是虛擬機(jī)內(nèi)的內(nèi)存,而是本地內(nèi)存。在元空間中保存的數(shù)據(jù)比永久代中純粹很多,就只是類的元數(shù)據(jù),這些信息只對(duì)編譯期或JVM的運(yùn)行時(shí)有用;
3、永久代有一個(gè)JVM本身設(shè)置固定大小上線,無(wú)法進(jìn)行調(diào)整,而元空間使用的是直接內(nèi)存,受本機(jī)可用內(nèi)存的限制,并且永遠(yuǎn)不會(huì)得到j(luò)ava.lang.OutOfMemoryError;
4、符號(hào)引用沒(méi)有存在元空間中,而是存在native heap中,這是兩個(gè)方式和位置,不過(guò)都可以算作是本地內(nèi)存,在虛擬機(jī)之外進(jìn)行劃分,沒(méi)有設(shè)置限制參數(shù)時(shí)只受物理內(nèi)存大小限制,即只有占滿了操作系統(tǒng)可用內(nèi)存后才OOM。