Java垃圾回收(二) 堆內存的分代回收

堆內存的分代回收

    Java針對堆的垃圾回收,將堆分爲了三個較小的部分:新生代、老年代、持久代。新生代主要使用複製和標記-清除垃圾回收算法,年老代主要使用標記-整理垃圾回收算法,因此java虛擬中針對新生代和年老代分別提供了多種不同的垃圾收集器。

1. 分代回收的依據:

  • 對象生存時間長短:大部分對象在Young期間就被回收。
  • 不同代採用不同的垃圾回收策略:對存活時間不同的對象分類,用不同的垃圾回收算法進行高效的有針對回收。

2. 堆內存的分代:

  • Young代

  •     回收機制:因爲對象數量少,所以採用複製(stop-and-copy)回收。
  •     組成區域:由1個Eden區和2個Survivor區構成,同一時間的兩個Survivor區,一個用來保存對象,另外一個是空的;絕大部分新生成的對象都放在Eden區,當Eden區將滿,JVM會因申請不到內存,而觸發Young GC ,進行Young代垃圾回收,就把Survivor的from區中可達對象複製到To區中,再清除Eden、From區,From區和To區互換,以便執行下一次的垃圾回收。一些生存時間長的對象直接分配到Old代中(關於生存時間長短,每次Young GC都會使Survivor區存活對象值+1,直到閾值)。
  •     對象來源:絕大多數對象先分配到Eden區,一些大的對象會直接被分配到Old代中。
  •     回收頻率:因爲Young代中大部分對象很快的進入不可達狀態,因此回收頻率高且回收速度快。

  • Old 代:

  •     回收機制:採用標記壓縮算法回收。(Concurrent-Mark–Sweep)
  •     對象來源:較大型的對象會直接進入Old代,另外再Young中生存的時間很長的可達對象也會進入Old代。
  •     回收頻率:因爲很少對象會死掉,所以頻率不高,而且每次回收的時間很長,因爲存在較多的大的對象。發生一次 Major GC 至少伴隨一次Young GC,一般比Young GC慢十倍以上。

  • Permanent代:

  •     用途:用來裝載Class,方法等信息,默認爲64M,不會被回收。
  •     對象來源:eg:動態生成類的時候,會不停的動態加載class文件,但是這些佔用的內存不會被回收,不停的加載會讓Permanent代的內存耗盡,會出現OOM的現象。
  • 回收頻率:不會被回收。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章