jvm垃圾回收机制_JVM 垃圾回收机制之堆的分代回收
JVM垃圾回收機制之堆的分代回收
前言
前文我們了解了Java的GC機制,對于堆中的對象,JVM采用引用計數和可達性分析兩種算法來標記對象是否可以清除,本文中我們還會了解到JVM將對分成了不同的區域,以便于更好的回收對象。
堆的分代
Java的堆是JVM中最大的一塊內存區域,主要保存Java中各種類的實例。為了更好的管理堆中各個對象的內存,包括分配內存和回收內存。
JVM將堆分成了幾塊區域:
新生代(Young)
新生代又分為:
Eden
From Survivor
To Survivor
老年代(Old)
其中新生代占堆的1/3空間,老年代占堆的2/3空間。
而新生代中的Eden占新生代的8/10,From Survivor和To Survivor各占新生代的1/10。
堆模型如圖:
從上圖中我們可以看出:堆是由新生代和老年代組成,默認情況下,新生代 ( Young ) 與老年代 ( Old ) 的比例為 1:2 。其中,新生代 ( Young ) 又分為 Eden 和 From Survivor 、To Survivor區域。默認情況下,Eden 和from、to的比例為 :8 : 1 : 1 。JVM 每次只會使用 Eden 和其中的一塊 Survivor 區域來為對象服務,所以無論什么時候,總是有一塊 Survivor 區域是空閑著的。因此,新生代實際可用的內存空間為 9/10 ( 即90% )的新生代空間。
堆的GC機制
堆中的GC分為兩種:
Minor GC
Full GC
Minor GC發生在新生代,采用的算法是復制算法。
Java中新創建的對象都在新生代中,當對象被判定為死亡時(也就是無法訪問),就會被GC回收內存,發生Minor GC時,會將Eden和From Survivor區域中的存活的對象復制到To Survivor區域中,然后將Eden和From survivor區域進行清理。
當一個對象活過了一次Minor GC后,它的年齡就加1,當對象的年齡達到了15時,對象就會被放入老年代。
Full GC發生在老年代,采用的是標記-清除算法。
標記:標記的過程其實就是,遍歷所有的GC Roots,然后將所有GC Roots可達的對象標記為存活的對象。
清除:清除的過程將遍歷堆中所有的對象,將沒有標記的對象全部清除掉。
當程序運行期間,若可以使用的內存被耗盡的時候,GC線程就會被觸發并將程序暫停,隨后將依舊存活的對象標記一遍,最終再將堆中所有沒被標記的對象全部清除掉,接下來便讓程序恢復運行。
標記-清除算法存在比較大的缺點:
進行GC時需要暫停應用程序,所以導致用戶體驗變差
會產生許多不連續的內存空間
所以我們一般會避免出現Full GC。
JVM參數
堆的初始大小、新生代、老年代的大小都可以通過JVM的參數進行配置。
下面是一些常用的JVM參數:
-Xms初始堆大小。如:-Xms256m-Xmx最大堆大小。如:-Xmx512m-Xmn新生代大小。通常為 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 個 Survivor 空間。實際可用空間為 = Eden + 1 個 Survivor,即 90%-Xss線程的堆棧大小-XX:NewRatio新生代與老年代的比例,如 –XX:NewRatio=2,則新生代占整個堆空間的1/3,老年代占2/3-XX:SurvivorRatio新生代中 Eden 與 Survivor 的比值。默認值為 8。即 Eden 占新生代空間的 8/10,另外兩個 Survivor 各占 1/10-XX:PermSize永久代(方法區)的初始大小-XX:MaxPermSize永久代(方法區)的最大值-XX:+PrintGCDetails打印 GC 信息
下面是Eclipse的JVM參數配置方法:
Window --- Preferences --- Java --- Installed JREs --- 點擊Edit
在Default VM arguments中添加參數:
總結
本文我們學習了JVM堆GC的分代機制,堆分為新生代和老年代,新生代中采用Minor GC,使用的是復制算法,老年代中采用Full GC,使用的是標記-清除算法。
總結
以上是生活随笔為你收集整理的jvm垃圾回收机制_JVM 垃圾回收机制之堆的分代回收的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python等腰梯形_简单空实心图形打印
- 下一篇: channelsftp 上传文件为空_S