天天看點

《深入了解JVM》之JVM堆記憶體

JVM堆記憶體分為2塊 : Permanent Space和Heap Space Permanent即持久代,主要存放java類定義資訊,與垃圾回收器要收集的java對象關系不大。用于存放靜态類型資料,如 Java Class, Method 等。但是有些應用可能動态生成或者調用一些Class,這時候需要設定一個比較大的持久代空間來存放這些運作中動态增加的類型。

Heap={Old+New={Eden,from,to}},old即年老代,New即年輕代。年老代和年輕代的劃分對垃圾收集影響比較大。 針對年輕代的垃圾回收即Young GC 年輕代一般分為三個區:1個Eden區,2個Survivor區 針對年老代的垃圾回收即Full GC 所有新生成的對象首先放在年輕代,年輕代的目标盡可能收集生命周期短的對象。 在年輕代中經曆了N次(可配置)垃圾回收後仍然存活的對象,就會被複制到年老代中。是以,可以認為年老代中存放的都是一些生命周期較長的對象。

是以,當一組對象生成時,記憶體申請過程如下: 1.JVM會試圖為相關Java對象在年輕代的Eden區中初始化一塊記憶體區域。 2.當Eden區空間足夠時,記憶體申請結束。否則執行下一步。 3.JVM試圖釋放在Eden區中所有不活躍的對象(Young GC)。釋放後若Eden空間仍然不足以放入新對象,JVM則試圖将部分Eden區中活躍對象放入Survivor區。 4.Survivor區被用來作為Eden區及年老代的中間交換區域。當年老代空間足夠時,Survivor區中存活了一定次數的對象會被移到年老代。 5.當年老代空間不夠時,JVM會在年老代進行完全的垃圾回收(Full GC)。 6.Full GC後,若Survivor區及年老代仍然無法存放從Eden區複制過來的對象,則會導緻JVM無法在Eden區為新生成的對象申請記憶體,即出現“Out of Memory”。

OOM(Out Of Memery)異常主要有以下2種原因 1、年老代溢出 java.lang.OutOfMemoryError:Javaheapspace 産生原因:設定的記憶體參數Xmx過小或者程式的記憶體洩漏及使用不當 例如:循環上萬次的字元串處理,建立上萬個對象,在一段代碼内申請上百M甚至上G記憶體

2、持久代溢出 java.lang.OutOfMemoryError:PermGenspace 由于持久代設定過小,動态加載了大量Java類而導緻溢出 解決方法:将參數 -XX:MaxPermSize 調大(一般256m能滿足絕大多數應用程式需求)。将部分Java類放到容器共享區

JVM初始記憶體的配置設定由-Xms指定,預設為實體記憶體的1/64但小于1G 最大記憶體的配置設定由-Xmx指定,預設為實體記憶體的1/4但小于1G -XX:NewRatio=參數 設定young與old的比例大小。 -XX:SurvivorRatio=參數 設定Eden與Survivor的比例大小,預設為32

繼續閱讀