JVM內存回收算法

4351fdce7b184a8996b3c90cb2b3225d.jpg1.1 引用計數法

?

每個對象創建的時候,會分配一個引用計數器,當這個對象被引用的時候計數器就加1,當不被引用或者引用失效的時候計數器就會減1。任何時候,對象的引用計數器值為0就說明這個對象不被使用了,就認為是“垃圾”,可以被GC處理掉。

?

【優點】算法實現簡單。

【缺點】不能解決對象之間循環引用的問題。有垃圾對象不能被正確識別,這對垃圾回收來說是很致命的,所以GC并沒有使用這種搜索算法。

1.2 根搜索算法

以一些特定的對象作為基礎原始對象,或者稱作“根”,不斷往下搜索,到達某一個對象的路徑稱為引用鏈。

如果一個對象和根對象之間有引用鏈,即根對象到這個對象是可到達的,則這個對象是活著的,不是垃圾,還不能回收。例如,假設有根對象O,O引用了A對象,同時A對象引用了B對象,B對象又引用了C對象,那么對象C和根對象O之間的路徑的可達的,C對象就不能當做垃圾對象。引用鏈為O->A->B->C。

反之,如果一個對象和根對象之間沒有引用鏈,根對象到這個對象的路徑是不可達的,那么這個對象就是可回收的垃圾對象。

?

?

【優點】可找到所以得垃圾對象,并且完美解決對象之間循環引用的問題。

【缺點】不可避免地要遍歷全局所有對象,導致搜索效率不高。

根搜索算法是現在GC使用的搜索算法。

?

可以當做GC roots的對象有以下幾種:

?

虛擬機棧中的引用的對象。(java棧的棧幀本地變量表)

?

方法區中的類靜態屬性引用的對象。

?

方法區中的常量引用的對象。(聲明為final的常量對象)

?

本地方法棧中JNI的引用的對象。(本地方法棧的棧幀本地變量表)

?

下面是從網上找來的圖,將就看看:GC ROOTS就是跟對象節點,藍色的是可達的引用鏈,引用鏈上的對象是活著的,不能被當做垃圾對象回收。相反暗灰色的路徑表示不可達的路徑,這些對象將會被回收。每個圈圈里面的數字,表示其被引用的次數,沒錯,就是上面說到的引用計數法的計數值。跟搜索算法示例圖

?

2.GC算法

這里討論的是oracle的Hotspot VM常見的垃圾回收算法。使用的搜索算法都是基于根搜索算法實現的。

?

2.1 標記-清除算法(Mark-Sweep)

該算法分兩步執行:

?

1) 標記Mark:從GC ROOTS開始,遍歷堆內存區域的所有根對象,對在引用鏈上的對象都進行標記。這樣下來,如果是存活的對象就會被做了標記,反之如果是垃圾對象,則沒做有標記。GC很容易根據有沒有被做標記就完成了垃圾對象回收。

?

2) 清除Sweep:遍歷堆中的所有的對象(標記階段遍歷的是所有根節點),找到未被標記的對象,直接回收所占的內存,釋放空間。

?

評價:

?

【優點】沒有產生額外的內存空間消耗,內存利用率高。

【缺點】效率低,清除階段要遍歷所有的對象;回收的垃圾對象是在各個角落的,直接回收垃圾對象,導致存在不連續的內存空間,產生內存碎片。

標記-清除算法操作的對象是【垃圾對象】,對于活著的對象(被標記的對象),它則直接不理睬。

?

2.2 復制算法(Copying)

復制算法把內存區間一分為二,有對象存在的一半區間稱為“活動區間”,沒有對象存在處于空閑狀態的空間則為“空閑區間”。

當內存空間不足時觸發GC,先采用根搜索算法標記對象,然后把活著的對象全部復制到另一半空閑區間上,復制算法的“復制”就來自這一操作。復制到另一半區間的時候,嚴格按照內存地址依次排列要存放的對象,然后一次性回收垃圾對象。

這樣原來的空閑區間在GC后就變成活動區間,而且內存順序齊整美觀。原來的活動區間在GC后就變成了完全空的空閑區間,等待下一次GC把活的對象被copy進來。

?

評價:

?

【優點】GC后的內存齊整,不產生內存碎片。

【缺點】GC要使用兩倍的內存,或者說導致堆只能使用被分配到的內存的一半,這個算法對空間要求太高!如果存活的對象較多,則意味著要復制很多對象并且要維護大量對象的內存地址,所以存活的對象數量不能太多,否則效率也會很低。

復制算法復制移動的對象是【活著的對象】,對于垃圾對象(不被標記的對象)則直接回收。

?

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

這個算法則是對上面兩個算法的綜合結果。也分為兩個階段:

?

1)標記:這個階段和標記-清除Mark-Sweep算法一樣,遍歷GC ROOTS并標記存活的對象。

?

2)整理:移動所有活著的對象到內存區域的一側(具體在哪一側則由GC實現),嚴格按照內存地址次序依次排列活著的對象,然后將最后一個活著的對象地址以后的空間全部回收。

?

評價:

?

【優點】內存空間利用率高,消除了復制算法內存減半的情況;GC后不會產生內存碎片。

?

【缺點】需要遍歷標記活著的對象,效率較低;復制移動對象后,還要維護這些活著對象的引用地址列表。

?

2.4 分代回收算法(Generational Collecting)

分代回收算法就是現在JVM使用的GC回收算法。

?

2.4.1簡要說明

1)先來看看簡單化后的堆的內存結構:

?

Java堆 = 年老代 + 年輕代

(空間大小比例一般是3:1)

?

年輕代 = Eden區 + From Space區 + To Space區

(空間大小比例一般是8:1:1)

2)按照對象存活時間長短,我們可以把對象簡單分為三類:

?

短命對象:存活時間較短的對象,如中間變量對象、臨時對象、循環體創建的對象等。這也是產生最多數量的對象,GC回收的關注重點。

?

長命對象:存活時間較長的對象,如單例模式產生的單例對象、數據庫連接對象、緩存對象等。

?

長生對象:一旦創建則一直存活,幾乎不死的對象。

?

3)對象分配區域

短命對象存在于年輕代,長命對象存在于年老代,而長生對象則存在于方法區中。

由于GC的主要內存區域是堆,所以GC的對象主要就是短命對象和長命對象這類壽命“有限”的對象。

?

2.4.2 分代回收的GC類型

針對HotSpot VM的的GC其實準確分類只有兩大種:

?

1)Partial GC:部分回收模式

?

Young GC:只收集young gen的GC。和Minor GC一樣。

Old GC:只收集old gen的GC。只有CMS的concurrent - collection是這個模式

Mixed GC:收集整個young gen以及部分old gen的GC。只有G1有這個模式

2)Full GC:收集整個堆,包括young gen、old gen,還有永久代perm gen(如果存在的話)等所有部分的模式。同Major GC。

?

3)觸發時機

HotSpot VM的串行GC的觸發條件是:

young GC:當young gen中的eden區分配滿的時候觸發。

?

full GC:當準備要觸發一次young GC時,如果發現統計數據說之前young GC的平均晉升大小比目前old gen剩余的空間大,則不會觸發young GC而是轉為觸發full GC;或者,如果有perm gen的話,要在perm gen分配空間但已經沒有足夠空間時,也要觸發一次full GC;或者System.gc()、heap dump帶GC,默認也是觸發full GC。

?

并發GC的觸發條件就不太一樣。以CMS GC為例,它主要是定時去檢查old gen的使用量,當使用量超過了觸發比例就會啟動一次CMS GC,對old gen做并發收集。

?

2.4.3 年輕代GC過程

當需要在堆中創建一個新的對象,而年輕代內存不足時觸發一次GC,在年輕代觸發的GC稱為普通GC,Minor GC。注意到年輕代中的對象都是存活時間較短的對象,所以適合使用復制算法。這里肯定不會使用兩倍的內存來實現復制算法了,牛人們是這樣解決的,把年輕代內存組成是80%的Eden、10%的From Space和10%的To Space,然后在這些內存區域直接進行復制。

?

剛開始創建的對象是在Eden中,此時Eden中有對象,而兩個survivor區沒有對象,都是空閑區間。第一次Minor GC后,存活的對象被放到其中一個survivor,Eden中的內存空間直接被回收。在下一次GC到來時,Eden和一個survivor中又創建滿了對象,這個時候GC清除的就是Eden和這個放滿對象的survivor組成的大區域(占90%),Minor GC使用復制算法把活的對象復制到另一個空閑的survivor區間,然后直接回收之前90%的內存。周而復始。始終會有一個10%空閑的survivor區間,作為下一次Minor GC存放對象的準備空間。

?

要完成上面的算法,每次Minor GC過程都要滿足:

存活的對象大小都不能超過survivor那10%的內存空間,不然就沒有空間復制剩下的對象了。但是,萬一超過了呢?前面我們提到過年老代,對,就是把這些大對象放到年老代。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/713646.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713646.shtml
英文地址,請注明出處:http://en.pswp.cn/news/713646.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

奇舞周刊第521期:“一切非 Rust 項目均為非法”

奇舞推薦 ■ ■ ■ 拜登:“一切非 Rust 項目均為非法” 科技巨頭要為Coding安全負責。這并不是拜登政府對內存安全語言的首次提倡。“程序員編寫代碼并非沒有后果,他們的?作?式于國家利益而言至關重要。”白宮國家網絡總監辦公室(ONCD&…

在idea中用模板骨架初始創建maven管理的web項目時沒有src有關的目錄的解決方案

一.問題如下 二.解決方法 首先關閉當前項目,接著修改全局設置,重新創建項目 在VM Options中添加"-DarchetypeCataloginternal",點擊ok保存 點擊創建,如果創建成功沒報錯且有src,就ok了。 當然如果出現以下…

「媒體宣傳」如何寫好新聞稿?

傳媒如春雨,潤物細無聲,大家好,我是51媒體網胡老師。 寫好新聞稿是媒體宣傳的關鍵環節之一,下面是一些關于如何寫好新聞稿的建議: 明確新聞稿的目的和受眾:在寫新聞稿之前,首先要明確新聞稿的目…

仿牛客網項目---帖子詳情功能的實現

這篇文章主要講講帖子詳情功能。其實帖子詳情功能簡單來說就是你點進去可以看到文章&#xff0c;這就叫帖子詳情功能。那接下來我講講我的這個項目是如何實現這個功能的。 首先寫DAO層。 Mapper public interface DiscussPostMapper {List<DiscussPost> selectDiscussPo…

StarRocks實戰——表設計規范與監控體系

目錄 前言 一、StarRocks表設計 1.1 字段類型 1.2 分區分桶 1.2.1 分區規范 1.2.2 分桶規范 1.3 主鍵表 1.3.1 數據有冷熱特征 1.3.2 大寬表 1.4 實際案例 1.4.1 案例一&#xff1a;主鍵表內存優化 1.4.2 案例一&#xff1a;Update內存超了&#xff0c;導致主鍵表導…

AI推薦算法的演進之路

推薦算法 基于大數據和AI技術&#xff0c;提供全流程一站式推薦平臺&#xff0c;協助企業構建個性化推薦應用&#xff0c;提升企業應用的點擊率留存率和永久體驗。目前&#xff0c;主要的推薦方法包括&#xff1a;基于內容推薦、協同過濾推薦、基于關聯規則推薦、基于效用推薦…

基于阿里云平臺 通過樹莓派實現 1:1人臉識別

之前的學習中&#xff0c;曾經在香橙派上使用阿里云平臺的服務實現過類型識別&#xff1a; 使用香橙派并基于Linux實現最終版智能垃圾桶項目 --- 下_香橙派 項目-CSDN博客 現在&#xff0c;嘗試在樹莓派上通過阿里云平臺的服務實現人臉識別&#xff01; 通過VScode遠程連接樹莓…

2024年新提出的算法|鸚鵡優化器(Parrot optimizer):算法及其在醫療問題中的應用

本期介紹一種基于訓練后鸚鵡關鍵行為的高效優化方法——鸚鵡優化器(Parrot Optimizer, PO)。該成果于2024年2月發表在中科院2區top SCI期刊Computers in Biology and Medicine&#xff08;IF7.7&#xff09; 1、簡介 鸚鵡優化器&#xff08;PO&#xff09;是一種受訓練有素的…

pytest教程-13-conftest.py文件

上一小節我們學習了fixture的作用域&#xff0c;本小節我們學習一下pytest conftest.py文件的使用方法。 conftest.py文件的作用 conftest.py文件是pytest框架中的一個特殊文件&#xff0c;用于定義共享的設置、夾具(fixture)和鉤子函數&#xff08;hook&#xff09;。 在py…

2.模擬問題——2.使用二維數組輸出圖形

用二維數組描述圖形 首先要計算出整個輸出的方框大小&#xff0c;從而判定相應關鍵循環點 #include <cstdio> char arr[1000][3000]; int main() {int h;//初始化&#xff0c;全部內部填空格while(scanf("%d",&h) ! EOF){for (int i 0; i < h; i) {f…

HTML---表單驗證

文章目錄 目錄 本章目標 一.表單驗證概述 二.表單選擇器 屬性過濾選擇器 三.表單驗證 表單驗證的方法 總結 本章目標 掌握String對象的用法會使用表單選擇器的選擇頁面元素會使用JQuery事件進行表單驗證Ajax的概念和作用 一.表單驗證概述 前端中的表單驗證是在用戶提交表…

圖神經網絡導論 - 劉知遠

一、神經網絡基礎 近年來&#xff0c;機器學習領域的發展迅速&#xff0c;主要表現在多種神經網絡架構的出現。盡管不同的神經網絡架構相差甚遠&#xff0c;但現有的神經網絡架構可以分為幾個類別&#xff1a; 卷積神經網路是前饋神經網路的特殊形式&#xff0c;FNN通常是全…

什么是VR虛擬現實|虛擬科技博物館|VR設備購買

虛擬現實&#xff08;Virtual Reality&#xff0c;簡稱VR&#xff09;是一種通過計算機技術模擬出的一種全新的人機交互方式。它可以通過專門的設備&#xff08;如頭戴式顯示器&#xff09;將用戶帶入一個計算機生成的虛擬環境之中&#xff0c;使用戶能夠與這個虛擬環境進行交互…

Spring Boot文檔目錄

目錄 官方文檔 說明&#xff1a;本文檔翻譯的版本&#xff1a;2.7.18-SNAPSHOT。 1. 法規&#xff08;Legal&#xff09; 2. 獲取幫助&#xff08;Getting Help&#xff09; 3. 文檔概述&#xff08;Documentation Overview&#xff09; 4. 開始使用&#xff08;Getting Sta…

BUUCTF---另外一個世界1

1.這是一道雜項題&#xff0c;也是我覺得最值得記錄的一道題。 2.話不多說&#xff0c;題目描述&#xff08;真的是另一個世界&#xff09; 3.下載附件&#xff0c;是一張圖片 4.嘗試了查看屬性&#xff0c;以及在記事本中打開看看有沒有什么有用的信息&#xff0c;發現沒什么…

FaceBook獲取廣告數據

1、訪問 廣告管理工具 確認自己登陸的賬號下面能看到戶。 ? 2、使用 圖譜Api探索工具 生成用戶短期口令 ? 3、get請求(或者瀏覽器直接打開)訪問&#xff1a; https://graph.facebook.com/v19.0/me?fieldsid,name, email&access_token{上一步生成的口令} ? 4、短期…

c# 獲取源碼路徑與當前程序所在路徑

獲取源碼路徑 private static string GetFilePath([CallerFilePath] string path null) {return path;}//當程序所在路徑string str67 System.Environment.CurrentDirectory;//源碼路徑 var path GetFilePath();var directory Path.GetDirectoryName(path);參考

Vue2:用node+express寫一個輕量級的后端服務

1、桌面創建demo文件夾 進入demo&#xff0c;執行如下命令 npm init輸入名稱&#xff1a; test_server然后一路回車 2、安裝express框架 npm i express3、新建server.js 在demo文件夾中&#xff0c;新建server.js const express require(express) const app express()…

2023年12月CCF-GESP編程能力等級認證Scratch圖形化編程三級真題解析

一、單選題(共15題,共30分) 第1題 現代計算機是指電子計算機,它所基于的是( )體系結構。 A:艾倫圖靈 B:馮諾依曼 C:阿塔納索夫 D:埃克特-莫克利 答案:B 第2題 默認小貓角色,執行下列程序,舞臺上會看到? ( ) A: B: C: D: 答案:C

干凈的語料沒有免疫力嗎?

干凈的語料指的是沒有雜音、無污染、無錯誤的語言材料。雖然干凈的語料本身沒有免疫力&#xff0c;但可以提供給機器學習算法或自然語言處理模型&#xff0c;幫助提高其性能和準確性。通過使用干凈的語料&#xff0c;可以降低噪聲干擾&#xff0c;減少模型的誤差&#xff0c;提…