metaspace腾降,顧名思義碌奉,元數(shù)據(jù)空間劝贸,專門用來存元數(shù)據(jù)的潮罪,它是jdk8里特有的數(shù)據(jù)結(jié)構(gòu)用來替代perm
metaspace出現(xiàn)背景
我們都知道jdk8之前有perm這一整塊內(nèi)存來存klass等信息康谆,我們的參數(shù)里也必不可少地會配置-XX:PermSize以及-XX:MaxPermSize來控制這塊內(nèi)存的大小,jvm在啟動的時候會根據(jù)這些配置來分配一塊連續(xù)的內(nèi)存塊嫉到,但是隨著動態(tài)類加載的情況越來越多沃暗,這塊內(nèi)存我們變得不太可控,到底設置多大合適是每個開發(fā)者要考慮的問題何恶,如果設置太小了孽锥,系統(tǒng)運行過程中就容易出現(xiàn)內(nèi)存溢出,設置大了又總感覺浪費细层,盡管不會實質(zhì)分配這么大的物理內(nèi)存惜辑。基于這么一個可能的原因疫赎,于是metaspace出現(xiàn)了盛撑,希望內(nèi)存的管理不再受到限制,也不要怎么關注元數(shù)據(jù)這塊的OOM問題捧搞,雖然到目前來看抵卫,也并沒有完美地解決這個問題。
metaspace的組成
- Klass Metaspace
- NoKlass Metaspace
Klass Metaspace
Klass Metaspace就是用來存klass的实牡,klass是我們熟知的class文件在jvm里的運行時數(shù)據(jù)結(jié)構(gòu)陌僵,不過有點要提的是我們看到的類似A.class其實是存在heap里的,是java.lang.Class的一個對象實例创坞。這塊內(nèi)存是緊接著Heap的碗短,和我們之前的perm一樣,這塊內(nèi)存大小可通過-XX:CompressedClassSpaceSize參數(shù)來控制题涨,這個參數(shù)前面提到了默認是1G偎谁,但是這塊內(nèi)存也可以沒有总滩,假如沒有開啟壓縮指針就不會有這塊內(nèi)存,這種情況下klass都會存在NoKlass Metaspace里巡雨,另外如果我們把-Xmx設置大于32G的話闰渔,其實也是沒有這塊內(nèi)存的,因為會這么大內(nèi)存會關閉壓縮指針開關铐望。還有就是這塊內(nèi)存最多只會存在一塊冈涧。
NoKlass Metaspace
NoKlass Metaspace專門來存klass相關的其他的內(nèi)容,比如method正蛙,constantPool等督弓,這塊內(nèi)存是由多塊內(nèi)存組合起來的,所以可以認為是不連續(xù)的內(nèi)存塊組成的乒验。這塊內(nèi)存是必須的愚隧,雖然叫做NoKlass Metaspace,但是也其實可以存klass的內(nèi)容锻全,上面已經(jīng)提到了對應場景狂塘。
Klass Metaspace和NoKlass Mestaspace都是所有classloader共享的,所以類加載器們要分配內(nèi)存鳄厌,但是每個類加載器都有一個SpaceManager荞胡,來管理屬于這個類加載的內(nèi)存小塊。如果Klass Metaspace用完了部翘,那就會OOM了硝训,不過一般情況下不會,NoKlass Mestaspace是由一塊塊內(nèi)存慢慢組合起來的新思,在沒有達到限制條件的情況下,會不斷加長這條鏈赘风,讓它可以持續(xù)工作夹囚。