大家好,我是鋒哥。今天分享關于【說下JVM中一次完整的GC流程?】面試題。希望對大家有幫助;
說下JVM中一次完整的GC流程?
1000道 互聯網大廠Java工程師 精選面試題-Java資源分享網
JVM中的一次完整的垃圾回收(GC)流程可以概括為以下幾個步驟:
1.?標記階段 (Mark)
- 目標:找出所有"存活"的對象。
- 過程:JVM的垃圾回收器首先通過從GC Root開始遍歷對象圖,標記所有可達的對象。GC Root通常是線程棧、靜態字段和本地方法棧等可以直接訪問的對象。
- 標記過程需要跟蹤從GC Root出發可達的對象,標記所有與GC Root有路徑連接的對象。
2.?清除階段 (Sweep)
- 目標:清除所有沒有被標記的對象,即"不可達"對象。
- 過程:GC將遍歷堆中的對象,將那些沒有被標記為可達的對象刪除。這個過程釋放內存空間,垃圾對象將被回收并且內存可重新分配。
- 注意:在某些情況下,如垃圾回收器沒有合并內存(例如Serial GC,Parallel GC等),清除后可能會導致內存碎片。
3.?整理階段 (Compact)
- 目標:防止內存碎片。
- 過程:如果是整理式垃圾回收(如Old Generation的Full GC),在回收不可達對象后,內存區域中的存活對象會被整理,使得這些對象緊湊地排列在一起。這樣做的目的是減少內存碎片,使得對象能夠高效地分配,避免頻繁的垃圾回收。
- 整理的過程一般會將存活的對象向內存區域的一端移動,合并出一個連續的大塊空閑內存區域。
4.?更新指針
- 目標:更新引用。
- 過程:經過標記和整理之后,可能會有一些對象的引用地址發生了變化。在這個階段,JVM會更新所有引用被回收對象的指針,使得它們指向新的位置。
5.?結束階段 (Finalization)
- 目標:執行對象的終結方法。
- 過程:在對象被回收之前,JVM可以調用對象的
finalize()
方法。如果該對象覆蓋了finalize()
方法,JVM會調用該方法用于做一些清理工作(如關閉資源等)。需要注意的是,finalize()
方法的調用并非是GC過程的一部分,且不是所有垃圾回收都會觸發它。
GC類型
JVM中有多種GC算法,其中最常見的幾種是:
- Serial GC:適合單線程環境,它在回收過程中會暫停整個應用線程。
- Parallel GC:多個線程并行工作,加速垃圾回收。
- CMS GC (Concurrent Mark-Sweep):并發回收標記階段和清除階段,以減少停頓時間。
- G1 GC:分代回收與并行回收相結合,目標是減少停頓時間,并且適應大堆內存的環境。
垃圾回收過程的細節
在不同的GC算法中,GC的過程會有所不同,特別是在停頓時間、并行性、內存整理等方面的表現。在實際應用中,選擇合適的垃圾回收算法對于提高JVM的性能至關重要。
小結
JVM中的垃圾回收流程大致如下:
- 標記階段:標記所有可達的對象。
- 清除階段:回收不可達的對象,釋放內存空間。
- 整理階段:整理內存,避免碎片。
- 更新指針:更新引用地址。
- 結束階段:調用
finalize()
方法(可選)。
在不同的GC算法中,標記、清理和整理的順序及策略可能有所不同,但大體流程一致。