一:JVM中內存
JVM中內存通常划分為兩個部分,分別為堆內存與棧內存,棧內存主要用運行線程方法
存放本地暫時變量與線程中方法運行時候須要的引用對象地址。
JVM全部的對象信息都
存放在堆內存中。相比棧內存,堆內存能夠所大的多,所以JVM一直通過對堆內存划分
不同的功能區塊實現對堆內存中對象管理。
堆內存不夠最常見的錯誤就是OOM(OutOfMemoryError)
棧內存溢出最常見的錯誤就是StackOverflowError。程序有遞歸調用時候最easy發生
二:堆內存划分
在JDK7以及其前期的JDK版本號中。堆內存通常被分為三塊區域Nursery內存(young
generation)、長時內存(old generation)、永久內存(Permanent Generation for
VM Matedata),顯演示樣例如以下圖:

當中最上一層是Nursery內存,一個對象被創建以后首先被放到Nursery中的Eden內
存中,假設存活期超兩個Survivor之后就會被轉移到長時內存中(Old Generation)中
永久內存中存放着對象的方法、變量等元數據信息。通過假設永久內存不夠。我們
就會得到例如以下錯誤:
java.lang.OutOfMemoryError: PermGen
而在JDK8中情況發生了明顯的變化,就是普通情況下你都不會得到這個錯誤,原因
在於JDK8中把存放元數據中的永久內存從堆內存中移到了本地內存(native memory)
中,JDK8中JVM堆內存結構就變成了例如以下:

這樣永久內存就不再占用堆內存。它能夠通過自己主動增長來避免JDK7以及前期版本號中
常見的永久內存錯誤(java.lang.OutOfMemoryError: PermGen),或許這個就是你的
JDK升級到JDK8的理由之中的一個吧。
當然JDK8也提供了一個新的設置Matespace內存
大小的參數。通過這個參數能夠設置Matespace內存大小,這樣我們能夠依據自己
項目的實際情況,避免過度浪費本地內存,達到有效利用。
-XX:MaxMetaspaceSize=128m 設置最大的元內存空間128兆
注意:假設不設置JVM將會依據一定的策略自己主動添加本地元內存空間。
假設你設置的元內存空間過小,你的應用程序可能得到下面錯誤:
java.lang.OutOfMemoryError: Metadata space
