一、JVM內存模型
JVM主要管理兩種類型內存:堆(Heap)和非堆(Permanent區域)。
1、Heap是運行時數據區域,所有類實例和數組的內存均從此處分配。Heap區分兩大塊,一塊是 Young Generation,另一塊是Old Generation:
1)在Young Generation中,有一個叫Eden Space的空間,主要是用來存放新生的對象,還有兩個Survivor Spaces(from,to),它們的大小總是一樣,它們用來存放每次垃圾回收后存活下來的對象。
2)在Old Generation中,主要存放應用程序中生命周期長的內存對象。
2、Permanent區:
Permanent Generation,主要是存儲的是java的類信息,包括解析得到的方法、屬性、字段等等。永久帶基本不參與垃圾回收。Permanent generation 不是Heap的一部。
.
二、內存大小
1、Heap內存分配
JVM初始分配的內存由-Xms指定,默認是物理內存的1/64;
JVM最大分配的內存由-Xmx指 定,默認是物理內存的1/4。
默認空余堆內存小於40%時,JVM 就會增大堆直到-Xmx 的最大限制,可以由 -XX:MinHeapFreeRatio 指定。
默認空余堆內存大於70%時,JVM 會減少堆直到-Xms的最小限制,可以由 -XX:MaxHeapFreeRatio 指定,
2、Permanent區域內存分配
JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;
由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。
1、JVM 會試圖為相關Java對象在Eden中初始化一塊內存區域。
2、當Eden空間足夠時,內存申請結束;否則到下一步。
3、JVM 試圖釋放在Eden中所有不活躍的對象(這屬於1或更高級的垃圾回收)。釋放后若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區。
4、Survivor區被用來作為Eden及Old的中間交換區域,當Old區空間足夠時,Survivor區的對象會被移到Old區,否則會被保留在Survivor區。
5、當Old區空間不夠時,JVM 會在Old區進行完全的垃圾收集(0級)。
6、完全垃圾收集后,若Survivor及Old區仍然無法存放從Eden復制過來的部分對象,導致JVM無法在Eden區為新對象創建內存區域,則出現”out of memory”錯誤。
參考:
java內存模型及GC原理 和 圖解JVM在內存中申請對象及垃圾回收流程