java的堆內存是如何被回收的?
以常見的CMS收集器進行說明,首先會對堆劃分為年輕代和年老代
Young區(年輕代),下面的默認的比例是 8:1:1Edge區To Survivor區From Survivor區Old區(年老代)對象優先分配在年輕代的Edge區,(如果對象過大,可以直接在old區分配,通過jvm參數可以設置這個閾值)
當Edge區塞不下,就需要回收空間騰地方(即觸發一次minorGC),(注意此時To Survivor是空的,From Survivor有存活對象)采用的原則是:
- 將Edge區和From Survivor區存活的對象塞到To Survivor區
- 完事之后,表示清空From Survivor和Edge中需要回收的對象,此時From Survivor就變成了新的 To Survivor區
看到這里一個問題就來了,如果To Survivor也塞不下這些數據怎么辦?
此時就需要把Survivor區的對象塞到Old區了,如果Old區也塞不下(沒有足夠大的連續空間來存儲這些對象),在會觸發FullGC,FullGC之后還塞不下,那就oom了
所以從上面這個流程中,可以得出一個結論FullGC必然伴隨一次MinorGC
額外說一句,內存分配和回收策略的內容并不只是上面這一點,建議看下廣受好評的《深入理解Java虛擬機-JVM高級特性與最佳實踐》
上一篇如何做網頁定位鏈接