1. 程式人生 > >這貨到底還是不是垃圾?【垃圾回收GC演算法JVM篇四】

這貨到底還是不是垃圾?【垃圾回收GC演算法JVM篇四】

目錄

  • 1、判斷物件是否存活的JVM兩種計數演算法
  • 2、垃圾收集演算法
  • 3、垃圾回收演算法小結

垃圾收集 Garbage Collection 通常被稱為“GC”, 在jvm 中,程式計數器、虛擬機器棧、本地方法棧都是隨執行緒而生隨執行緒而滅,棧幀隨著方法的進入和退出做入棧和出棧操作,實現了自動的記憶體清理,因此,我們的記憶體垃圾回收主要集中於 java 堆和方法區中,在程式執行期間,這部分記憶體的分配和使用都是動態的!

@

既然是垃圾回收,那肯定要知道什麼是垃圾了是吧,我相信哪一天落魄java開發宜春小哥哥去撿垃圾維持生活,哈氣、一juo、彎腰、開蓋、倒水,一氣呵成我閉著眼,把廣東靚仔沒喝完的快樂肥宅水錯當垃圾撿了,這廣東靚仔還不得打人?是的,而JVM的垃圾收集的前提就是明確啥是垃圾!JVM首先會進行一系列計數演算法判斷是不是垃圾。在JVM認為是否是垃圾的評判標準為物件是否存活,物件存活就不是垃圾,不能進行回收,反之進行回收。

1、判斷物件是否存活的JVM兩種計數演算法

判斷物件是否存活的JVM兩種計數演算法主要有兩種,分別是:引用計數、可達性分析計數演算法。

一聽到計數演算法中有“ 演算法 ”二字,小白童鞋發愣了:媽呀,數學不好,完了,不學了...咳咳咳,咋們不提演算法,從咋們的日常生活開始著手,在我們平時一個東西經常沒被使用,而且也用不上什麼地方,那麼這個東西可以說就是垃圾。其實在 Java 中也是如此,如果一個物件不可能再被引用,那麼這個物件就是垃圾,應該被回收。就是這麼簡單粗暴,JVM兩種計數演算法就是這樣子的,真的不復雜。

1.1、引用計數演算法

根據我們生活上的思想,我們很容易想到使用引用計數的方法來判斷垃圾。在一個物件被引用時加一,被去除引用時減一,這樣我們就可以通過判斷引用計數是否為0來判斷一個物件是否為垃圾。這種方法我們一般稱之為「引用計數法」。確實賊簡單的一個思路也正是以為它的簡單,從而存在缺陷,因此引用計數演算法是這樣定義的

1、引用計數:每個物件有一個引用計數屬性,新增一個引用時計數加1,引用釋放時計數減1,計數為0時可以回收。
2、正因方法簡單,從而引用計數演算法無法解決物件相互迴圈引用的問題。

小白童鞋可能不知道啥是物件迴圈引用,熊dei看圖

1.2、可達性分析計數演算法

首先宣告一點:在實際開發語言比如java、C#等都是採用可達性分析計數演算法判斷物件是否存活!

可達性分析演算法的定義如下:

可達性分析(Reachability Analysis):從GC Roots開始向下搜尋,搜尋所走過的路徑稱為引用鏈。當一個物件到GC Roots沒有任何引用鏈相連時,則證明此物件是不可用的。不可達物件。

相信很容易看出,其實都很好理解,唯獨GC Roots有點抽象,那啥是GC Roots呢?在Java語言中,GC Roots主要包括:

1、物件的引用,位於虛擬機器棧中。
2、方法區中的靜態引用。
3、本地方法棧中JNI的引用。【JNI一般指的是Native方法】
簡單地說,GC Root 就是經過精心挑選的一些引用


像上面的迴圈引用的這種情況引用計數演算法是無法進行GC掉的,而根搜尋演算法可以做到,因此引用計數演算法存在缺陷!根搜尋演算法更好!

2、垃圾收集演算法

以上內容概述了啥垃圾,接下來就要講講如何進行回收垃圾!在生活中我們收集垃圾,可以一邊走一邊掃,也可以把垃圾全都掃到一起再一次清理。在JVM中,類似生活,提供了一系列的垃圾收集演算法。

而且我們還經常能看到垃圾分類,分成可回收垃圾,和不可回收垃圾,但是從某一意義上來講,還都是垃圾,如果人人都遵守垃圾分類規則,我估計以後收破爛的大叔大媽都天天從可回收垃圾桶下手了,其實在JVM中也類似如此,JVM採取了分割槽、分代收集的思想。

常見的垃圾回演算法:標記清除演算法、複製演算法、標記整理演算法、分代收集演算法。

2.1、標記清除演算法複製演算法

標記清除演算法。從名字可以看到其分為兩個階段:標記階段和清除階段。一種可行的實現方式是,在標記階段,標記所有由 GC Root 觸發的可達物件。此時,所有未被標記的物件就是垃圾物件。之後在清除階段,清除所有未被標記的物件。標記清除演算法最大的問題就是空間碎片問題。如果空間碎片過多,則會導致記憶體空間的不連續。雖說大物件也可以分配在不連續的空間中,但是效率要低於連續的記憶體空間。

2.2、複製演算法(Copying)

複製(Copying)演算法。複製演算法的核心思想是將原有的記憶體空間劃分為大小相等的兩塊,每次只使用一塊,在垃圾回收時,將正在使用的記憶體中的存活物件複製到未使用的記憶體塊中。之後清除正在使用的記憶體塊中的所有物件,之後交換兩個記憶體塊的角色,完成垃圾回收。複製演算法的缺點是要將記憶體空間折半,極大地浪費了一半記憶體空間。因此現在的商業虛擬機器都使用這種複製演算法來進行新生代的垃圾收集!因為在物件存活率高的時候,複製演算法就顯得效率低下

2.3、標記-整理演算法(Mark-Compact)

關於標記-整理演算法還有一種叫法是標記壓縮演算法,知道其說的同一者就好了。

標記整理演算法。標記整理演算法可以說是標記清除演算法的優化版,其同樣需要經歷兩個階段,分別是:標記階段、整理階段。在標記階段,從 GC Root 引用集合觸發去標記所有物件,和標記清除演算法中的標記階段是一樣一樣的。在整理階段,其則是將所有存活的物件整理在記憶體的一邊,之後清理邊界外的所有空間。因此,標記-整理演算法(Mark-Compact)不會產生記憶體碎片,但是會多花點時間用在整理(Compact)上面!

2.4、分代收集演算法(Generational Collection)

“分代收集”(Generational Collection)演算法,把Java堆分為新生代和老年代,這樣就可以根據各個年代的特點採用最適當的收集演算法。在新生代中,每次垃圾收集時都發現有大批物件死去,只有少量存活,那新生代選用複製演算法,只需要付出少量存活物件的複製成本就可以完成收集。而老年代中因為物件存活率高、沒有額外空間對它進行分配擔保,老年代就使用“標記-清理”或“標記-整理”演算法來進行回收。

2.5、四種回收演算法總結

標記清除演算法

分為標記階段和清除兩階段。標記清除演算法最大的問題就是空間碎片問題。比較適合在存活物件比較多的情況。

複製演算法(Copying)

複製演算法的缺點是浪費了一半記憶體空間。現在的商業虛擬機器都使用這種複製演算法來進行新生代的垃圾收集!因為在物件存活率高的時候,複製演算法就顯得效率低下比較適合存活物件比較少的情況。

標記整理演算法(Mark-Compact)

標記整理演算法是標記清除演算法的優化版,標記-整理演算法(Mark-Compact)不會產生記憶體碎片,但是會多花點時間用在整理(Compact)上面!

分代收集演算法(Generational Collection)

新生代選用複製演算法,老年代使用“標記-清理”或“標記-整理”演算法來進行回收。

3、垃圾回收演算法小結

借用大佬整理的一張圖:

如果本文對你有一點點幫助,那麼請點個讚唄,謝謝~

最後,若有不足或者不正之處,歡迎指正批評,感激不盡!如果有疑問歡迎留言,絕對第一時間回覆!

歡迎各位關注我的公眾號,裡面有一些java學習資料和一大波java電子書籍,比如說周志明老師的深入java虛擬機器、java程式設計思想、核心技術卷、大話設計模式、java併發程式設計實戰.....都是java的聖經,不說了快上Tomcat車,咋們走!最主要的是一起探討技術,嚮往技術,追求技術,說好了來了就是盆友喔...

相關推薦

到底還是垃圾垃圾回收GC演算法JVM

目錄 1、判斷物件是否存活的JVM兩種計數演算法 2、垃圾收集演算法 3、垃圾回收演算法小結 垃圾收集 Garbage Collection 通常被稱為“GC”, 在jvm 中,程式計數器、虛擬

Web自動化測試——代碼常用方法——常見元素操作

fin pack 百度輸入 submit .get ted baidu 百度搜 內容 瀏覽器這個大框架我們都能控制,區區頁面小元素又能奈我們何!!!之前的【Web自動化測試——代碼篇二】條條大路找元素 已經講述了許多獲取元素的方法,在此基礎上我們來認識幾個元素最常見的相關操

Jupyter notebook安裝目前會使用。。。嗯。。。

首先,安裝Jupyter Notebook需要你的電腦裡安裝過python,第一步,就是看看你的pip版本: 輸入python -m pip list 發現我的pip需要升級。。。。那就輸入python -m pip install --upgrade pi

PHP7 流程控制和函式 習題輸入一個整數,判斷這個數字是是質數。

一、什麼是質數?   質數又稱素數。一個大於1的自然數,除了1和它本身外,不能整除其他自然數的數叫做質數;否則稱為合數。 二、思路分析: 定義一個表示,預設值為 true(預設為質數); 判斷輸入的數是否大於零,若為否,則提示 “輸入正整數”;

別翻了,文章絕對讓你深刻理解java類的載入以及ClassLoader原始碼分析JVM

目錄 1、什麼是類的載入(類初始化) 2、類的生命週期 3、介面的載入過程 4、解開開篇的面試題 5、理解首次主動使用 6、類載入器 7、關於名稱空間

JVM中的GC演算法,JVM引數,垃圾收集器分類

一.在JVM中什麼是垃圾?如何判斷一個物件是否可被回收?哪些物件可以作為GC Roots的根   垃圾就是在記憶體中已經不再被使用到的空間就是垃圾.   1.引用計數法:     內部使用一個計數器,當有物件被引用+1,沒有就-1,但是沒有辦法解決迴圈引用的問題,JVM不採用此類回收法   2.列舉根節點可達

JVM垃圾回收GC演算法

# 1 GC演算法簡介 |演算法| 特點 | |--|--| |**標記-清除**| 分為“標記”和“清除”兩個階段| |**複製**|可以解決效率問題,將可用的記憶體按容量劃分為大小相等的兩塊。| |**標記-整理** | 先標記、再整理,最後清理 | |**分代收集**|劃分新生代和老年代| # 2 標

DockerMesos+Zookeeper+Marathon+Docker實戰實驗

開發工具 簡化 mark too 資源調度 ext 網絡 上線 root Apache Mesos概述 不同的分布式運算框架(spark,hadoop,ES,MPI,Cassandra,etc.)中的不同任務往往需要的資源(內存,CPU,網絡IO等)不同,它們運行在同一個集

Web自動化測試——代碼常用方法——切換

final src fire desktop sta begin 新的 med 目前 方法總覽 Java Python Ruby 多表單切換 指定表單 switchTo().frame(id/name/定位元素) switch_to.frame(id/name

Web自動化測試——代碼常用方法——鼠標鍵盤事件

回退 uil let 百度 home build 測試 chains nbsp Java Python Ruby 鼠標事件 右擊 Actions action = new Actions(driver); action.contextClick(inputBo

Web自動化測試——代碼常用方法——上傳/下載文件

.com instance timeunit 鍵盤 .sh exception lse NPU 組合 上傳文件 對於Web頁面的上傳功能實現一般有一下倆種方式: 普通上傳:將本地文件的路徑作為一個值放在input標簽中,通過form表單將這個值提交給服務器(不做介紹sen

python3的學習之路十IO編程

函數 詳細 遇到 作文件 否則 truncate inux load remove File(文件) 方法 file 對象使用 open 函數來創建 file.close() 關閉文件。關閉後文件不能再進行讀寫操作。 file.flush(

網際網路+時代七個引爆點正合奇勝

一、什麼是“正合奇勝” 百度百科: 正合奇勝,用正兵合戰,以奇兵取勝。正:指用常規戰法對付常規戰法。奇:指用隱祕莫測、出敵不意的戰法制服常規戰法。 《孫子兵法·勢篇》: “凡戰者,以正合,以奇勝。故善出奇者,無窮如天地,不竭如江河。” 百度知道: 孫子推崇“正合奇勝”的軍爭之道,

數論知識系統複習 根據一本通提高總結 待更

說在前面: 仔細閱讀一本通提高篇,會發現它挺齊全的,綜合了別的書籍的一些好的例題,還是很走心了。 因為已經是自己的總結了 ∴會更切合考試——實用性強,方便複習。 (關閉兩邊的廣告也OK) 歡迎

iOS-cocos2d-X 遊戲開發之Cocos2dX建立Android NDK新專案並編譯匯入Eclipse中正常執行!

站文章均為 李華明Himi 原創,轉載務必在明顯處註明: 轉載自【黑米GameDev街區】 原文連結: http://www.himigame.com/android-game/645.html          ☞ 點選訂閱 ☜ 本部落格最新動態

Network Charles 抓包(原理

目前網上提供了很多篇文章是用來介紹在mac上使用Charles抓取手機App的網路包(簡而言之就是——抓包)。抓包操作是我們必須掌握的一項技能,但是我發現網上整理的抓包方法不是太詳細,所以我在此重新寫一下抓包的步驟。 (1)抓包首先是要安裝mac端的Charles。(Ch

Git+Source Tree使用教程之Reset

Reset Here is our current repo: With the Book has the following: AnnabelLee BY EDGAR ALLAN POE 1809-1849Publishedin1849Update A Update

OpenCV人臉識別入門教程之LBP人臉識別

本文使用OpenCV實現攝像頭實時LBP人臉識別,這裡不講解LBP人臉識別的原理,小路孩會另外專門寫特徵提取的系列部落格,到時會詳細講解LBP特徵,敬請關注。才疏學淺,有錯誤在所難免,歡迎指正。 系統:Windows7;OpenCV版本:2.4.10. 一、準備工作 1

java 菜鳥自動化實踐之將資料庫查詢資料,轉為TestNG適用的物件二維陣列資料

資料庫資料:資料庫操作:import java.sql.*; import org.apache.log4j.Logger; public class MysqlConn { private static Logger log = Logger.getLogger(My

OpenCV影象處理入門學習教程基於LoG運算元的影象邊緣檢測

一、基於LoG運算元的影象邊緣檢測原圖:1.LoG運算元與自定義濾波運算元進行比較的結果:2.LoG運算元的結果:3.自定義3*31 1 1 1 -8 1 1 1 1 濾波結果:二、程式碼解析下面是一段基於LoG運算元的影象邊緣檢測的程式碼,同時會生成兩個結果,一個是LoG運算元的結果,第二個是自