第四章 JVM垃圾回收演算法

来源:http://www.cnblogs.com/java-zhao/archive/2016/02/05/5183261.html
-Advertisement-
Play Games

說明:在閱讀本篇之前,需要知道怎麼判斷對象的存活與否,見《第三章 JVM記憶體回收區域+對象存活的判斷+引用類型+垃圾回收線程》 註意:本文主要參考自《分散式Java應用:基礎與實踐》,與《深入理解Java虛擬機(第二版)》中的一些說法有一些不同,但是原理一致 1、三種垃圾回收演算法 標記-清除(年老代


說明:在閱讀本篇之前,需要知道怎麼判斷對象的存活與否,見《第三章 JVM記憶體回收區域+對象存活的判斷+引用類型+垃圾回收線程

註意:本文主要參考自《分散式Java應用:基礎與實踐》,與《深入理解Java虛擬機(第二版)》中的一些說法有一些不同,但是原理一致

 

1、三種垃圾回收演算法

  • 標記-清除(年老代)
  • 標記-整理(即標記-壓縮)(年老代)
  • 複製(年輕代)

1.1、標記-清除演算法

原理

  • 從根集合節點進行掃描,標記出所有的存活對象,最後掃描整個記憶體空間並清除沒有標記的對象(即死亡對象)

適用場合

  • 存活對象較多的情況下比較高效
  • 適用於年老代(即舊生代)

缺點

  • 容易產生記憶體碎片,再來一個比較大的對象時(典型情況:該對象的大小大於空閑表中的每一塊兒大小但是小於其中兩塊兒的和),會提前觸發垃圾回收
  • 掃描了整個空間兩次(第一次:標記存活對象;第二次:清除沒有標記的對象)

註意:

 

1.2、標記整理演算法

原理:

  • 從根集合節點進行掃描,標記出所有的存活對象,最後掃描整個記憶體空間並清除沒有標記的對象(即死亡對象)(可以發現前邊這些就是標記-清除演算法的原理),清除完之後,將所有的存活對象左移到一起。

適用場合:

  • 用於年老代(即舊生代)

缺點:

  • 需要移動對象,若對象非常多而且標記回收後的記憶體非常不完整,可能移動這個動作也會耗費一定時間
  • 掃描了整個空間兩次(第一次:標記存活對象;第二次:清除沒有標記的對象)

優點:

  • 不會產生記憶體碎片

註意:

 

1.3、複製演算法

原理:

  • 從根集合節點進行掃描,標記出所有的存活對象,並將這些存活的對象複製到一塊兒新的記憶體(圖中下邊的那一塊兒記憶體)上去,之後將原來的那一塊兒記憶體(圖中上邊的那一塊兒記憶體)全部回收掉

適用場合:

  • 存活對象較少的情況下比較高效
  • 掃描了整個空間一次(標記存活對象並複製移動)
  • 適用於年輕代(即新生代):基本上98%的對象是"朝生夕死"的,存活下來的會很少

缺點:

  • 需要一塊兒空的記憶體空間
  • 需要複製移動對象

註意:

  • 在該情況下,記憶體規整,對象的記憶體分配採用"指針碰撞法",見《第二章 JVM記憶體分配
  • 以空間換時間:通過一塊兒空記憶體的使用,減少了一次掃描

 

2、垃圾回收機制

根據《第一章 JVM記憶體結構》所說,年輕代分為Eden區和survivor區(兩塊兒:from和to),且Eden:from:to==8:1:1

1)新產生的對象優先分配在Eden區(除非配置了-XX:PretenureSizeThreshold,大於該值的對象會直接進入年老代);

2)當Eden區滿了或放不下了,這時候其中存活的對象會複製到from區(這裡,需要註意的是,如果存活下來的對象from區都放不下,則這些存活下來的對象全部進入年老代),之後Eden區的記憶體全部回收掉;註意:如果是Eden區沒有滿,但是來了一個小對象Eden區放不下,這時候Eden區存活對象複製到from區後,清空Eden區,之後剛纔的小對象再進入Eden區

3)之後產生的對象繼續分配在Eden區,當Eden區又滿了或放不下了,這時候將會把Eden區和from區存活下來的對象複製到to區(同理,如果存活下來的對象to區都放不下,則這些存活下來的對象全部進入年老代),之後回收掉Eden區和from區的所有記憶體;

4)如上這樣,會有很多對象會被覆制很多次(每複製一次,對象的年齡就+1),預設情況下,當對象被覆制了15次(這個次數可以通過:-XX:MaxTenuringThreshold來配置),就會進入年老代了

5)當年老代滿了或者存放不下將要進入年老代的存活對象的時候,就會發生一次Full GC(這個是我們最需要減少的,因為耗時很嚴重)

 

總結:

  • 年輕代:複製演算法
  • 年老代:標記-清除或標記-整理(前者相較於後者會快一些但是會產生記憶體碎片,後者相較於前者不會產生記憶體碎片但是由於要移動存活對象所以會慢一些)
  • 以上這種年輕代與年老代分別採用不同回收演算法的方式稱為"分代收集演算法",這也是當下企業使用的一種方式
  • 每一種演算法都會有很多不同的垃圾回收器去實現,在實際使用中,根據自己的業務特點做出選擇就好

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、三元運算 我們在上章學習的if,,else,,有一種簡便的方法 他的表達式是這樣的:變數 = 值1 if 條件 else 值2 解釋過來就是如果aaa等於sss則輸出值1否則輸出值2 二、類的概念 類是面向對象編程的核心, 它扮演相關數據及邏輯的容器角色。它們提供了創建“真實” 對象(也就是實例
  • 練習: 輸入詩的名稱查詢出詩的內容,當輸入exit時,退出程式,“春曉”,“靜夜思”,“鵝”。 package CollectionPart; public class Poetry { private String title; private String poet; private Strin
  • 說明:垃圾回收演算法是理論,垃圾收集器是回收演算法的實現,關於回收演算法,見《第四章 JVM垃圾回收演算法》 1、七種垃圾收集器 Serial(串列GC) ParNew(並行GC) Parallel Scavenge(並行回收GC) Serial Old(MSC)(串列GC) CMS(併發GC) Paral
  • 今天分享一個 企業級的通用鏈表庫設計和一個簡單字元串設計. 封裝一個簡單的開發框架還是比較麻煩的, 或者說說封裝一個簡單的基庫都挺麻煩的. 全當分享吧. 簡單扯一點,封裝庫其實難點在 前期是設計,中期是演算法,瓶頸在結構和語法解析上.
  • Java Magic. Part 1: java.net.URL @(Base)[JDK, url, magic, 黑魔法] " 英文原文 " 廢話不多說,首先我們看如下代碼: 代碼的第3行和第5行分別會輸出什麼呢? 當然不會是true, 如果是true的話,這篇文章也就不會有java黑魔法的尾碼了
  • 一.通配符上限和通配符下限接受的類型 通配符上限:<? extends T> 通配符下限:<? super T> 以下代碼是測試結果,註釋為解釋說明 1 package xayd.hjj; 2 3 import java.util.ArrayList; 4 import java.util.List
  • 我們知道list存儲的是有序不唯一的元素。 set存儲的是無序唯一的元素。 那麼下麵看一個例子吧: package CollectionPart; import java.util.HashSet; import java.util.Set; public class HashSet1 { publ
  • Python可以說是爬網的利器,本文主要介紹了一些python來模擬http請求的一些方法和技巧。 Python處理請求的類庫有兩個,urllib,urllib2。 這兩個類庫並不是一個類庫的兩個不同版本,urllib主要用來處理一些url相關的內容,發送請求的時候,請求對象只能是一個url。url
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...