垃圾回收器相關概念

垃圾收集器分類

  • 垃圾收集器沒有在規範中進行過多的規定,可以由不同的廠商、不同版本的JVM來實現。
  • 由於JDK的版本處於高速迭代過程中,因此Java發展至今已經衍生了衆多的GC版本。
  • 從不同角度分析垃圾收集器,可以將GC分爲不同的類型。
  1. 按線程數分,可以分爲串行垃圾回收器和並行垃圾回收器。
  2. 按照工作模式分,可以分爲併發式垃圾回收器和獨佔式垃圾回收器。
  3. 按碎片處理方式分,可分爲壓縮武垃圾回收器和非壓縮式垃圾回收器。壓縮式垃圾回收器會在回收完成後,對存活對象進行壓縮整理,消除回收後的碎片(指針碰撞)。非壓縮式的垃圾回收器不進行這步操作(空閒列表)。
  4. 按工作的內存區間分,又可分爲年輕代垃圾回收器和老年代垃圾回收器。

性能指標

  • 吞吐量:運行用戶代碼的時間佔總運行時間的比例(總運行時間:程序的運行時間+內存回收的時間)
  • 垃圾收集開銷:吞吐量的補數,垃圾收集所用時間與總運行時間的比例。
  • 暫停時間:執行垃圾收集時,程序的工作線程被暫停的時間。
  • 收集頻率:相對於應用程序的執行,收集操作發生的頻率。
  • 內存佔用:Java 堆區所佔的內存大小。
  • 快速:一個對象從誕生到被回收所經歷的時間。

標紅的這三者共同構成一個“不可能三角”。三者總體的表現會隨着技術進步而越來越好。一款優秀的收集器通常最多同時滿足其中的兩項。這三項裏,暫停時間的重要性日益凸顯。因爲隨着硬件發展,內存佔用多些越來越能容忍,硬件性能的提升也有助於降低收集器運行時對應用程序的影響,即提高了吞吐量。而內存的擴大,對延遲反而帶來負面效果。簡單來說, 主要抓住兩點:吞吐量和暫停時間

  • 吞吐量就是CPU用於運行用戶代碼的時間與CPU總消耗時間的比值,即吞吐量=運行用戶代碼時間/ (運行用戶代碼時間+垃圾收集時間)。比如:虛擬機總共運行了100分鐘,其中垃圾收集花掉1分鐘,那吞吐量就是99%。
  • 這種情況下,應用程序能容忍較高的暫停時間,因此,高吞吐量的應用程序有更長的時間基準,快速響應是不必考慮的。
  • “暫停時間”是指一個時間段內應用程序線程暫停,讓G線程執行的狀態.例如,GC期間100毫秒的暫停時間意味着在這100毫秒期間內沒有應用程序線程是活動的。
  • 吞吐量優先,意味着在單位時間內,STW的時間最短: 0.2 + 0.2 = 0.4
  • 暫停時間優先,意味着儘可能讓單次STW的時間最短: 0.1 + 0.1 + 0.1 + 0.1 + 0.1 = 0.5
    在這裏插入圖片描述

高吞吐量較好因爲這會讓應用程序的最終用戶感覺只有應用程序線程在做“生產性”工作。直覺上,吞吐量越高程序運行越快。

低暫停時間(低延遲)較好因爲從最終用戶的角度來看不管是GC還是其他原因導致一個應用被掛起始終是不好的。這取決於應用程序的類型,有時候甚至短暫的200毫秒暫停都可能打斷終端用戶體驗。因此,具有低的較大暫停時間是非常重要的,特別是對於一個交互式應用程序

不幸的是”高吞吐量”和”低暫停時間”是-對相互競爭的目標(矛盾)。因爲如果選擇以吞吐量優先,那麼必然需要降低內存回收的執行頻率,但是這樣會導致GC需要更長的暫停時間來執行內存回收。相反的,如果選擇以低延遲優先爲原則,那麼爲了降低每次執行內存回收時的暫停時間,也只能頻繁地執行內存回收,但這又引起了年輕代內存的縮減和導致程序吞吐量的下降。

在設計(或使用) Gc算法時,我們必須確定我們的目標:一個GC算法只可能針對兩個目標之一(即只專注於較大吞吐量或最小暫停時間),或嘗試找到一個二者的折衷。現在標準:在最大吞吐量優先的情況下,降低停頓時間。

7個經典收集器

垃圾收集器發展史
在這裏插入圖片描述

7個經典收集器與垃圾分代之間的關係圖
在這裏插入圖片描述
垃圾收集器的組合關係最新圖(jdk14之前),(虛線是jdk8不包括jdk8之前的關係,實線是jdk8之後的關係)
在這裏插入圖片描述
爲什麼要有很多收集器,一個不夠嗎?因爲Java的使用場景很多,移動端,服務器等。所以就需要針對不同的場景,提供不同的垃圾收集器,提高垃圾收集的性能。
雖然我們會對各個收集器進行比較,但並非爲了挑選一個最好的收集器出來。沒有一種放之四海皆準、任何場景下都適用的完美收集器存在,更加沒有萬能的收集器。所以我們選擇的只是對具體應用最合適的收集器

-XX: +PrintCommandLineFlags:查看命令行相關參數(包含使用的垃圾收集器)
使用命令行指令:jinfo-flag 相關垃圾回收器參數進程ID

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章