從大的方面來講,JVM的內存模型分為兩大塊:
永久區內存( Permanent space)和堆內存(heap space)。
棧內存(stack space)一般都不歸在JVM內存模型中,因為棧內存屬于線程級別。
每個線程都有個獨立的棧內存空間。
Permanent space里存放加載的Class類級對象如class本身,method,field等等。
heap space主要存放對象實例和數組。
heap space由Old Generation和NewGeneration組成,OldGeneration存放生命周期長久的實例對象,而新的對象實例一般放在NewGeneration。
New Generation還可以再分為Eden區(圣經中的伊甸園)、和Survivor區,新的對象實例總是首先放在Eden區,Survivor區作為Eden區和Old區的緩沖,可以向Old區轉移活動的對象實例。
一般,我們常見的OOM(out of memory)內存溢出異常,就是堆內存空間不足以存放新對象實例時導致。
永久區內存溢出相對少見,一般是由于需要加載海量的Class數據,超過了非堆內存的容量導致。通常出現在Web應用剛剛啟動時,因此Web應用推薦使用預加載機制,方便在部署時就發現并解決該問題。
棧內存也會溢出,但是更加少見。
堆內存優化:
調整JVM啟動參數-Xms -Xmx -XX:newSize -XX:MaxNewSize,如調整初始堆內存和最大對內存 -Xms256M -Xmx512M。 或者調整初始New Generation的初始內存和最大內存-XX:newSize=128M -XX:MaxNewSize=128M。
永久區內存優化:
調整PermSize參數 如 -XX:PermSize=256M-XX:MaxPermSize=512M。
棧內存優化:
調整每個線程的棧內存容量 如 -Xss2048K
最終,一個運行中的JVM所占的內存= 堆內存 + 永久區內存 + 所有線程所占的棧內存總和 。