更新時間:2022-06-02 10:13:48 來源:動力節(jié)點 瀏覽2008次
什么是Java垃圾回收機制?動力節(jié)點小編來為大家解答。
垃圾收集是一種自動收集某個程序不再需要的內存區(qū)域并使該內存區(qū)域可供其他程序使用的技術。
程序的處理在垃圾回收執(zhí)行過程中停止。因此,垃圾收集能否正常運行,極大地影響了系統(tǒng)性能。
程序中使用new創(chuàng)建的 Java 對象,占用 JavaVM 管理的內存空間。從創(chuàng)建 Java 對象到它變得多余的時間段稱為Java對象的生命周期。
Java 對象有兩種類型;壽命短的和壽命長的。對于在服務器上運行的 Java 應用程序,許多 Java 對象由請求和響應或事務管理創(chuàng)建。這些 Java 對象的生命周期很短,因為它們在處理結束時變得多余。另一方面,在應用程序運行時不斷使用的 Java 對象具有較長的生命周期。
為了有效地執(zhí)行垃圾回收,您需要通過對生命周期短的對象執(zhí)行垃圾回收來使內存回收有效。避免對重復使用的長壽命對象進行不必要的垃圾回收,有助于防止系統(tǒng)性能下降。這是通過按代垃圾收集來實現(xiàn)的。
在按代垃圾回收中,Java 對象通過將它們分成兩個區(qū)域進行管理;存儲壽命短的對象的 New 區(qū)域和存儲壽命長的對象的 Tenured 區(qū)域。New 區(qū)域進一步分為 Eden 區(qū)域和 Survivor 區(qū)域,Eden 區(qū)域保存最近使用new創(chuàng)建的對象,Survivor 區(qū)域保存即使多次運行垃圾收集后仍未收集的對象。執(zhí)行垃圾收集超過固定次數(shù)的New區(qū)域的Java對象被認為是長期需要的Java對象,這些Java對象移動到Tenured區(qū)域。
下圖顯示了內存空間和按代垃圾回收管理的 Java 對象的概覽:

分代垃圾回收執(zhí)行的垃圾回收有以下兩種類型:
復制垃圾收集
復制垃圾收集僅針對 Eden 區(qū)域和 Survivor 區(qū)域。當您使用 Eden 區(qū)域創(chuàng)建 Java 對象時,會發(fā)生復制垃圾收集。
您可以通過指定 Java HotSpot VM 選項來選擇串行復制垃圾收集和并行復制垃圾收集。
因為串行復制垃圾回收的處理是并行執(zhí)行的,所以可以高速執(zhí)行并行復制垃圾回收。但是,如果您選擇并行復制垃圾回收,則無法使用顯式管理堆功能。
默認選擇串行復制垃圾收集。請注意,本章介紹的內容適用于這兩種類型的復制垃圾回收。
對一個對象執(zhí)行復制垃圾回收的次數(shù)稱為對象的年齡。
下圖顯示了一個對象的壽命和年齡之間的關系:

應用程序啟動后,初始化過程完成,復制垃圾回收已經(jīng)執(zhí)行了多次,長期需要的長壽命對象移動到Tenured區(qū)。結果,在啟動應用程序后不久,Java 堆就達到了穩(wěn)定狀態(tài),并且大多數(shù)創(chuàng)建的 Java 對象都是生命周期較短的對象。特別是,如果新區(qū)域的調整已經(jīng)適當執(zhí)行,那么在 Java 堆穩(wěn)定后,大部分生命周期較短的對象都會在第一次復制垃圾回收期間被回收。
在JavaVM中,執(zhí)行復制垃圾回收的New區(qū)的內存空間被劃分為Eden區(qū)和Survivor區(qū)。Survivor 區(qū)域進一步分為 From 空間和 To 空間。From 空間和 To 空間具有相同的內存大小。
下圖是New區(qū)域的配置:

Eden 區(qū)域是最初存儲使用new創(chuàng)建的對象的區(qū)域。當在程序中執(zhí)行new時,會分配來自 Eden 區(qū)域的內存。
當 Eden 區(qū)域變滿時,將執(zhí)行復制垃圾回收。復制垃圾回收中進行如下處理:
在 Eden 區(qū)域和 Survivor 區(qū)域的 From 空間中存在的 Java 對象中,正在使用的對象被復制到 Survivor 區(qū)域的 To 空間。未使用的 Java 對象將被銷毀。
Survivor 區(qū)域的 To 空間和 From 空間被交換。
結果,Eden 區(qū)域和 To 空間變?yōu)榭?,而正在使用的對象保留?From 空間中。
將那些年齡未達到閾值的 Java 對象移動到 Tenured 區(qū)域的活動稱為Saving。當 Eden 區(qū)域和 From 空間中正在使用的對象數(shù)量增加并且這些對象將被移動到的 To 空間的內存大小不足以在復制垃圾回收期間保存這些對象時,就會發(fā)生保存。在這種情況下,無法移動到 To 空間的對象將移動到 Tenured 區(qū)域。

當對象被保存時,原本不應該保存在Tenured區(qū)的壽命短的對象,被保存到Tenured區(qū)。如此反復,本應通過復制垃圾回收來回收的對象不斷在內存空間中累積,從而增加 Java 堆的內存使用量,最終發(fā)生完整的垃圾回收。
在 JavaVM中,除了 Eden 區(qū)域、Survivor 區(qū)域和 Tenured 區(qū)域之外,您還可以使用稱為Explicit heap的區(qū)域。垃圾回收不在顯式堆區(qū)域中執(zhí)行。
使用自動分配設置文件和顯式內存管理功能 API 指定要保存在顯式堆區(qū)域中的對象。在指定對象從 Survivor 區(qū)域移動到 Tenured 區(qū)域的時刻,指定對象被移動到 Explicit heap 區(qū)域。您可以指定沒有被復制垃圾回收回收的長生命周期的對象,以減少Tenured區(qū)的內存使用,并防止完全垃圾回收的發(fā)生。您還可以使用顯式內存管理功能或顯式內存管理功能 API 的自動分配設置文件在顯式堆區(qū)域中創(chuàng)建指定對象。