JVM(4)

垃圾回收問題

垃圾回收算法

通過之前的學習我們可以將死亡對象標記出來了,標記出來后我們就可以進行垃圾回收操作了,在正式學習垃圾處理器之前,我們先來看一下垃圾回收器使用的幾種算法.

標記-清除算法

"標記-清除"算法是基礎的收集算法.算法分為"標記"和"清除"兩個階段:首先標記出所有需要回收的對象,在標記完成后統一回收所有被標記的對象.后續的收集算法都是基于這種思路加以改造并對其不足加以改進而已:

"標記-清除"算法的不足主要有兩個:
1.效率問題:標記和清除這兩個過程的效率都不高.

2.空間問題:標記清除后會產生大量不連續的內存碎片,內存碎片太多可能會導致以后在程序運行中需要分配較大對象時,無法找到足夠連續內存而不得不提前觸發另一次垃圾收集.

?復制算法

?"復制算法是為了解決"標記-清理"的效率問題.它將可用內存按容量劃分為大小相等的兩塊,每次只使用其中的一塊.當這塊內存需要進行垃圾回收時,會將此區域還存活著的對象復制到另一塊上面,然后再把已經使用過的內存區域一次清理掉.這樣做的好處是每次都對整個半區進行內存回收,內存分配時也就不需要考慮內存碎片等復雜的情況,只需要移動堆頂指針,按順序分配即可.此算法實現簡單,運行高效.算法的執行流程如下圖:

通過復制算法這種機制確實能在一定程度上規避內存問題,但也有一定缺陷.

1.總的可用內存,變少了.

2.如果每次要復制的對象比較多,此時復制的開銷比較大,需要的是當前一輪(當中,大部分對象被釋放,少數對象存活,在這個時候最適合復制).?

現在的商用虛擬機(包括HotSpot都是采用這種收集算法來回收新生代)

引入概念:對象的年齡.JVM有專門的線程負責掃描/釋放一個對象,如果被線程掃描的時候,可達了(不是垃圾), 年齡+1 =>在對象類中存儲年齡.

?新生代中98%的對象都是"朝生暮死"的,所以不需要按照1:1的比例來劃分內存空間,而是將內存(新生代內存)分為一塊較大的Eden(伊甸園)空間和兩塊較小的Survivor(幸存者空間),每次使用Eden和其中一塊Survivor(兩個Survivor區域一個稱為from區,另一個稱為To區).當回收時,將Eden和Survivor中還存活的對象一次性復制到另一塊Survivor空間上,最后清理掉Eden和剛才用過的Survivor的空間.

當Survivor空間不夠用的時候,需要依賴其它內存(老年代)機型分配擔保.

HotSpot默認Eden與Survivor的大小比例是8:1,也就是說:Eden : Survivor From : Survivor To = 8:1:1.所以每次新生代的可用空間為整個新生代容量的90%,而剩下的10%用來存放回收后存活的對象.

下面來看一下具體的算法執行流程:

(1)當代碼中new出一個對象,這個對象就是被創建在伊甸區的,伊甸區能有很多對象.一個經驗規律:伊甸區的對象都是"朝生暮死"的,生命周期非常短.

(2)第一輪GC掃描完成之后,少數伊甸區中幸存的對象就會通過算法拷貝到生存區,后續GC掃描線程還會持續進行掃描,不僅會掃描伊甸區,也會掃描生存區的對象,生存區中也有大量對象被標記為垃圾,少數存活的,就會使用算法,拷貝到另一個生存區中.只要這個能夠在生存區中繼續存活,就會被復制算法,拷貝到另一個生存區中,每經過一次GC掃描,對象年齡+1

(3) 如果該對象存儲在生存區中,經歷了若干輪GC依然健在,JVM就會認為,這個對象生命周期大概率會很長,就把這個對象從生存區拷貝到老年代.

(4)老年代對象,也會被GC掃描,但是掃描的頻次大大降低.

(5)當對象在老年代中壽終正寢的時候,JVM按標記整理的方式,進行清除.

標記-整理算法

復制收集算法在對象存活率較高時會進行比較多的復制操作,效率會變低.因此老年代一般不能使用復制算法.

針對老年代的特點,提出了一種稱之為"標記-整理算法".標記過程仍與"標記-清除"的過程一致,但后續的步驟不是直接對可回收對象進行整理,而是讓所有存活對象都向一端移動,然后清理掉邊界以外的內存.流程圖如下:

?分代算法

分代算法和上面講的三種算法不同,分代算法是通過區域的劃分,實現不同區域和不同的垃圾回收策略,從而實現更好的垃圾回收.就好比中國的一國兩制方針一樣,對于不同的情況和地域設置更符合當地的規則,從而實現更好的管理,這就是分代算法的設計思想.

當前JVM垃圾收集器采用的是"分代收集"算法,這個算法并沒有新思想,只是根據對象的存活周期的不同將內存劃分為幾塊.一般是把Java堆分為新生代和老年代.在新生代中,每次垃圾回收都有大批對象死去,只有少量存活,因此我們采用復制算法;而老年代中對象存活率高,沒有額外空間對它進行分配擔保,就必須采用"標記-清理"或者"標記-整理"算法.

哪些對象會進入新生代?哪些對象會進入老年代?

新生代:一般創建的對象都會進入新生代;

老年代:大對象經歷了N次(默認情況下是15次)垃圾回收依然存活下來的對象會從新生代移動到老年代.

面試問題:請問了解Minor GC和Full GC么,這兩種GC有什么不一樣嗎?

1.Minor GC又稱為新生代GC:指的是發生在新生代的垃圾收集.因為Java對象大多都具有朝生暮死的特性,因此Minor GC(采用復制算法)的使用非常頻繁,一般回收速度也比較快.

2.Full GC又稱為老年代GC或者Major GC:指發生在老年代的垃圾收集.出現了Major GC,經常會伴隨至少一次的Minor GC(并非絕對,在Parallel Scavenge收集器中就有直接進行Full GC的策略選擇過程).Major GC的速度一般會比Minor GC慢10倍以上.?

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

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

相關文章

「Vue3系列」Vue3指令

文章目錄 一、Vue3 指令二、注冊-自定義指令三、常見自定義指令1. 聚焦指令(v-focus)2. 高亮指令(v-highlight)3. 防抖指令(v-debounce)4. 限制輸入指令(v-limit)使用注意事項 四、相…

WPF中如何設置自定義控件

1.圓角按鈕的設置: 眾所周知在WPF中自帶有提示信息,當我問創建Button時,點擊空格出現如下可選設置 帶有小扳手🔧圖標為相應的屬性,如果Button有CornerRadius(角半徑)屬性就能夠直接設置Button實…

33. 【Linux教程】Linux 用戶組

前面小節介紹了 Linux 用戶相關的增刪改查,本小節介紹 Linux 用戶組,Linux 系統中采取了一種安全機制(即用戶組),用戶組可以允許多個 Linux 用戶共享同一種權限。 1. 用戶組介紹 Linux 是多任務多用戶的操作系統&…

鴻蒙Harmony應用開發—ArkTS聲明式開發(自定義事件分發)

ArkUI在處理觸屏事件時,會在觸屏事件觸發前進行按壓點和組件區域的觸摸測試,來收集需要響應觸屏事件的組件,再基于觸摸測試結果分發相應的觸屏事件。在父節點,開發者可以通過onChildTouchTest決定如何讓子節點去做觸摸測試&#x…

【AI Agent系列】【MetaGPT多智能體學習】5. 多智能體案例拆解 - 基于MetaGPT的智能體辯論(附完整代碼)

本系列文章跟隨《MetaGPT多智能體課程》(https://github.com/datawhalechina/hugging-multi-agent),深入理解并實踐多智能體系統的開發。 本文為該課程的第四章(多智能體開發)的第三篇筆記。主要是對課程剛開始環境搭…

Linux系統——Shell腳本——一鍵安裝LNMP

#!/bin/bash #安裝nginx echo "安裝nginx服務" wget http://nginx.org/download/nginx-1.11.4.tar.gz &>/dev/null if [ $? -eq 0 ] thenecho "nginx-1.11.4安裝包下載完成"echo "--開始安裝必要的依賴文件--"yum install -y gcc gcc-c…

python中map函數

map(str, path): map函數會將path中的每一個元素傳遞給str函數,從而將它們轉換為字符串。 如果path是一個數字列表,例如[1, 2, 3],那么map(str, path)將返回[1, 2, 3]。 在寫二叉樹時用到map給樹節點進行str轉換是錯的。 map(s…

xsslabs第五關

看一下源碼 <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv"content-type" content"text/html;charsetutf-8"> <script> window.alert function() { confirm("完成的不錯&#xff01…

MATLAB知識點:條件判斷 if-elseif-else-end語句

?講解視頻&#xff1a;可以在bilibili搜索《MATLAB教程新手入門篇——數學建模清風主講》。? MATLAB教程新手入門篇&#xff08;數學建模清風主講&#xff0c;適合零基礎同學觀看&#xff09;_嗶哩嗶哩_bilibili 節選自?第4章&#xff1a;MATLAB程序流程控制 if、elseif、…

webstorm 創建運行純Typescript項目

創建一個空項目&#xff0c;在項目根目錄創建一個tsconfig.json文件自動配置&#xff1a; 打開終端輸入tsc --init&#xff0c;即可自動生成tsconfig.json文件手動配置&#xff1a; 在項目根目錄下新建一個tsconfig.json文件,并配置如下內容 具體配置可以直接使用下面的配置&am…

【JavaEE】_Spring MVC項目之建立連接

目錄 1. Spring MVC程序編寫流程 2. 建立連接 2.1 RequestMapping注解介紹 2.2 RequestMapping注解使用 2.2.1 僅修飾方法 2.2.2 修飾類與方法 2.3 關于POST請求與GET請求 2.3.1 GET請求 2.3.2 POST請求 2.3.3 限制請求方法 1. Spring MVC程序編寫流程 1. 建立連接&…

如何開好一家汽車美容店,汽車美容保養與裝飾教學

一、教程描述 本套教程共由17張VCD組合而成&#xff0c;教程內容主要包括&#xff1a;美容店的設立和管理&#xff0c;汽車系統與內部結構&#xff0c;汽車美容工具與美容設備&#xff0c;美容用品的選擇與使用&#xff0c;車身打蠟鍍膜與內外清潔&#xff0c;車身拋光與漆面處…

Debezium發布歷史162

原文地址&#xff1a; https://debezium.io/blog/2023/09/22/debezium-2-4-cr1-released/ 歡迎關注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻譯&#xff0c;僅供參考&#xff0c;筆芯筆芯. Debezium 2.4.0.CR1 Released September 22, 2023 by Chris Cranford r…

(介紹與使用)物聯網NodeMCUESP8266(ESP-12F)連接新版onenet mqtt協議實現上傳數據(溫濕度)和下發指令(控制LED燈)

前言 本文詳細介紹了如何利用物聯網技術,通過NodeMCU ESP8266(ESP-12F)模塊連接到新版的OneNet平臺,使用MQTT協議實現數據的上傳與指令的下發。文中首先對NodeMCU ESP8266模塊及其特性進行了簡介,隨后詳細闡述了如何配置和使用MQTT協議連接到OneNet平臺,實現溫濕度數據的…

Azkaban 大數據 任務調度

參考視頻&#xff1a;尚硅谷大數據Azkaban 3.x教程&#xff08;全新發布&#xff09;_嗶哩嗶哩_bilibili Azkaban&#xff1a; 是一個定時、批量工作流任務調度器(工作流程調度&#xff0c;定時調度) 常見的開源調度系統&#xff1a; 簡單單一的任務調度&#xff1a; Linux的…

嵌入式驅動學習第一周——Linux錯誤碼以及 IS_ERR、ERR_PTR、PTR_ERR

前言 本節來學習Linux錯誤碼&#xff0c;因為內核中的函數常常返回指針&#xff0c;如果出錯&#xff0c;也希望能夠通過返回的指針體現出來。 嵌入式驅動學習專欄將詳細記錄博主學習驅動的詳細過程&#xff0c;未來預計四個月將高強度更新本專欄&#xff0c;喜歡的可以關注本博…

【正點原子STM32】RNG硬件隨機數(隨機數發生器、真隨機和偽隨機、應用場景、RNG結構和原理、RNG相關寄存器和HAL庫驅動、RNG基本驅動步驟)

一、RNG簡介 二、RNG框圖介紹 三、RNG相關寄存器介紹 四、RNG相關HAL庫驅動介紹 五、RNG基本驅動步驟 六、編程實戰 七、總結 一、RNG簡介 隨機數發生器&#xff08;RNG&#xff09;在計算機科學和密碼學中具有廣泛的應用場景&#xff0c;包括但不限于以下幾個方面&#xff1a…

QML中動態表格修改數據

1.qml文件中的實現代碼 import QtQuick 2.15 import QtQuick.Window 2.15import QtQuick.Controls 2.0 import Qt.labs.qmlmodels 1.0 import QtQuick.Layouts 1.15Window {width: 640height: 480visible: truetitle: qsTr("Hello World")TableModel{id:table_model…

Python內置函數11——globals()、locals()

文章目錄 概要基礎用法 概要 globals()和locals()都是內置函數&#xff0c;用于獲取當前命名空間中的變量。 globals()函數返回全局命名空間的字典&#xff0c;包括全局變量、函數和模塊。它返回一個表示全局命名空間的字典。你可以使用該函數來查看和修改全局命名空間中的變量…

深入剖析k8s-控制器思想

引言 本文是《深入剖析Kubernetes》學習筆記——《深入剖析Kubernetes》 正文 控制器都遵循K8s的項目中一個通用的編排模式——控制循環 for {實際狀態 : 獲取集群中對象X的實際狀態期望狀態 : 獲取集群中對象X的期望狀態if 實際狀態 期望狀態 {// do nothing} else {執行…