1. 程式人生 > >什麼是 GC, gc 概述,垃圾回收機制

什麼是 GC, gc 概述,垃圾回收機制

什麼是 GC

1.JVM 的 gc 概述

gc( garbage collection) : 即垃圾收集, 是指 JVM 用於釋放那些不再使用的物件所佔用的記憶體。

java 語言並不要求 JVM 有 gc, 也沒有規定 gc 如何工作。 不過常用的 JVM 都有 gc, 而且大多數 gc 都使用類似的演算法
管理記憶體和執行收集操作。

在充分理解了垃圾收集演算法和執行過程後, 才能有效的優化它的效能。 有些垃圾收集專用於特殊的應用程式。 比如, 實時應用程式主要是為了避免垃圾收集中斷, 而大多數 OLTP 應用程式則注重整體效率。

理解了應用程式的工作負荷和 JVM 支援的垃圾收集演算法, 便可以進行優化配置垃圾收集器。 垃圾收集的目的在於清除不再使用的物件, gc 通過確定物件是否被活動物件引用來確定是否收集該物件。 gc 首先要判斷該物件是否是時候可以收集, 引用計數和物件引用遍歷是兩種常用的方法。

引用計數:

引用計數儲存對特定物件的所有引用數, 也就是說, 當應用程式建立引用以及引用超出範圍時, JVM 必須適當
增減引用數。 當某物件的引用數為 0 時, 便可以進行垃圾收集。

物件引用遍歷:

早期的 JVM 使用引用計數, 現在大多數 JVM 採用物件引用遍歷。

物件引用遍歷從一組物件開始, 沿著整個物件圖上的每條連結, 遞迴確定可到達( reachable) 的物件。 如果某物件不能從這些根物件的一個( 至少一個)到達, 則將它作為垃圾收集。

在物件遍歷階段, gc 必須記住哪些物件可以到達, 以便刪除不可到達的物件,這稱為標記( marking) 物件。 下一步, gc 要刪除不可到達的物件。

刪除時, 有些 gc 只是簡單的掃描堆疊,刪除未標記的物件, 並釋放它們的記憶體以生成新的物件, 這叫做清除( sweeping) 。

這種方法的問題在於記憶體會分成好多小段, 而它們不足以用於新的物件, 但是組合起來卻很大。 因此, 許多 gc 可以重新組織記憶體中的物件, 並進行壓縮( compact) , 形成可利用的空間。

為此, gc 需要停止其他的活動。 這種方法意味著所有與應用程式相關的工作停止, 只有 gc 執行。 結果, 在響應期間增減了許多混雜請求。

另外, 更復雜的 gc 不斷增加或同時執行以減少或者清除應用程式的中斷。 有的 gc 使用單執行緒完成這項工作, 有的則採用多執行緒以增加效率。

Java 語言沒有提供釋放已分配記憶體的顯示操作方法。

程式設計師可以手動執行 System.gc(), 通知 GC 執行, 但是 Java 語言規範並不保證 GC 一定會執行。

2.幾種垃圾回收機制

·標記-清除收集器

這種收集器首先遍歷物件圖並標記可到達的物件, 然後掃描堆疊以尋找未標記物件並釋放它們的記憶體。 這種收
集器一般使用單執行緒工作並停止其他操作。

·標記-壓縮收集器
有時也叫標記-清除-壓縮收集器, 與標記-清除收集器有相同的標記階段。 在第二階段, 則把標記物件複製
到堆疊的新域中以便壓縮堆疊。 這種收集器也停止其他操作。

·複製收集器

這種收集器將堆疊分為兩個域, 常稱為半空間。 每次僅使用一半的空間, JVM 生成的新物件則放在另一半空間
中。 gc 執行時, 它把可到達物件複製到另一半空間, 從而壓縮了堆疊。 這種方法適用於短生存期的物件, 持
續複製長生存期的物件則導致效率降低。

·增量收集器

增量收集器把堆疊分為多個域, 每次僅從一個域收集垃圾。 這會造成較小的應用程式中斷。

·分代收集器

這種收集器把堆疊分為兩個或多個域, 用以存放不同壽命的物件。 JVM 生成的新物件一般放在其中的某個域
中。 過一段時間, 繼續存在的物件將獲得使用期並轉入更長壽命的域中。 分代收集器對不同的域使用不同的算
法以優化效能。

·併發收集器

併發收集器與應用程式同時執行。 這些收集器在某點上( 比如壓縮時) 一般都不得不停止其他操作以完成特定
的任務, 但是因為其他應用程式可進行其他的後臺操作, 所以中斷其他處理的實際時間大大降低。

·並行收集器

並行收集器使用某種傳統的演算法並使用多執行緒並行的執行它們的工作。 在多 CPU 機器上使用多執行緒技術可以顯
著的提高 java 應用程式的可擴充套件性。