了解GC嗎?什么是GC?

GC是什么?為什么要GC?

GC( Garbage Collection ),垃圾回收,是Java與C++的主要區別之一。作為Java開發者,一般不需要專門編寫內存回收和垃圾清理代碼。這是因為在Java虛擬機中,存在自動內存管理和垃圾清理機制。對JVM中的內存進行標記,并確定哪些內存需要回收,根據一定的回收策略,自動的回收內存,保證JVM中的內存空間,防止出現內存泄露和溢出問題。

GC是任意時候都能進行的嗎

GC垃圾收集只能在安全點才能進行。在Java虛擬機(JVM)中,安全點(Safe Point)是程序執行的某些特定位置。JVM只能在安全點安全地暫停執行,從而進行垃圾回收(GC)等操作。安全點的設定確保了當線程暫停時,程序的狀態是可知和一致的。

如何判斷一個對象是否存活?

引用計數法

給對象中添加一個引用計數器,每當有一個地方引用它,計數器就加 1;當引用失效,計數器就減 1;任何時候計數器為 0 的對象就是不可能再被使用的。

優點:可即刻回收垃圾,當對象計數為0時,會立刻回收;

弊端:循環引用時,兩個對象的計數都為1,導致兩個對象都無法被釋放。JVM不用這種算法

可達性分析算法

通過 GC Root 對象為起點,從這些節點向下搜索,搜索所走過的路徑叫引用鏈,當一個對象到 GC Root沒有任何的引用鏈相連時,說明這個對象是不可用的。

  • JVM中的垃圾回收器通過可達性分析來探索所有存活的對象

  • 掃描堆中的對象,看能否沿著GC Root對象為起點的引用鏈找到該對象,如果找不到,則表示可以回收

GC Root的對象有哪些?

  • 虛擬機棧(棧幀中的本地變量表)中引用的對象,例如各個線程被調用的方法棧用到的參數、局部變量或者臨時變量等。

  • 方法區中類靜態屬性引用的對象或者說Java類中的引用類型的靜態變量。

  • 方法區中常量引用的對象或者運行時常量池中的引用類型變量。

  • 本地方法棧中JNI(即一般說的Native方法)引用的對象

  • JVM內部的內存數據結構的一些引用、同步的監控對象(被修飾同步鎖)。

finalize()方法的作用?

finalize() 類似 C++ 的析構函數,用來做關閉外部資源等工作。但是 try-finally 等方式可以做的更好,并且該方法運行代價高昂,不確定性大,無法保證各個對象的調用順序,因此最好不要使用。(Java 9中已棄用)

當一個對象可被回收時,如果需要執行該對象的 finalize() 方法,那么就有可能通過在該方法中讓對象重新被引用,從而實現自救。自救只能進行一次,如果回收的對象之前調用了 finalize() 方法自救,后面回收時不會調用 finalize() 方法。

Java種有哪些引用類型?有什么特點?

  • 強引用:gc時不會回收

  • 軟引用:只有在內存不夠用時,gc才會回收

  • 弱引用:只要gc就會回收;弱引用對象非常適合于實現 Map 的緩存(weakHashMap),當對象只通過弱引用可達時,可以快速釋放內存。

  • 虛引用:是否回收都找不到引用的對象,僅用于管理直接內存

什么時候需要安全點?安全點的觸發條件?

安全點的作用:

  • 垃圾收集: 在進行垃圾收集時,JVM需要暫停所有應用程序線程(GC暫停),以確保不會有線程在操作內存。同時,狀態的快照是確定的,以便于GC工作。
  • 堆棧遍歷: 在執行如線程轉儲(Thread Dump)等操作時,JVM需要安全地遍歷線程棧,這時也需要安全點。
  • 性能損耗最小化: 通過在最可能長時間運行的指令設置安全點(例如循環的末端、方法的調用與返回),JVM可以減少程序暫停的頻率,從而降低性能損耗。

安全點的觸發條件:

  1. 方法調用:每次方法調用都是一個潛在的安全點。
  2. 循環回跳:長時間循環中間會插入安全點檢查。
  3. 異常處理:處理異常時,也會檢查是否到達安全點。

young Gc、old Gc、full Gc 和 mixed Gc 的區別是什么?

Young GC(Minor GC或 YGC),即年輕代垃圾回收:

  • 作用范圍:僅針對新生代(Eden和S0/S1)。
  • 觸發條件:當新生代內存(尤其是 Eden 區)被填滿時觸發。
  • 執行方式:只回收新生代中的對象,老年代不受影響。
  • 特點:回收頻率較高,回收時間較短,因為新生代中的對象大多數是短命對象,容易被回收。

Old Gc(Major GC或OGC),老年代垃圾回收:

  • 作用范圍:只針對老年代。
  • 觸發條件:當老年代空間不足時觸發,通常是當從新生代晉升到老年代的對象過多,或者老年代的存活對象數量達到一定閾值時。
  • 執行方式:只回收老年代的對象,新生代不受影響。
  • 特點:執行時間比 Young GC 長,因為老年代中的對象存活時間更長,且數量較多

Full GC,全堆垃圾回收:

  • 作用范圍:對整個堆內存(包括新生代和老年代)進行回收。
  • 觸發條件:當老年代空間不足且無法通過老年代垃圾回收釋放足夠空間,或其他情況導致系統內存壓力較大時觸發(如 system.gc()調用)
  • 執行方式:回收所有代(新生代、老年代)中的垃圾,并且可能會伴隨著元空間的回收。
  • 特點:回收時間最長,會觸發整個JM 的停頓(Stop-The-World),對性能有較大影響,通常不希望頻繁發生

Mixed Gc(僅適用于 G1 GC 的混合垃圾回收):

  • 作用范圍:同時回收新生代和部分老年代區域
  • 觸發條件:當 G1垃圾回收器發現老年代區域的垃圾過多時觸發。
  • 執行方式:混合回收新生代和部分老年代區域,主要目的是減少老年代中的垃圾積壓。
  • 特點:結合了 YGC 的快速回收和 OGC的深度回收,盡量減少停頓時間,適用于大內存應用

對象在堆中的生命周期?

  1. 在 JVM 內存模型的堆中,堆被劃分為新生代和老年代

    • 新生代又被進一步劃分為 Eden區Survivor區From SurvivorTo Survivor
  2. 當創建一個對象時,對象會被優先分配到新生代的 Eden 區

    • 此時 JVM 會給對象定義一個對象年輕計數器 -XX:MaxTenuringThreshold
  3. 當 Eden 空間不足時,JVM 將執行新生代的垃圾回收(Minor GC)

    • JVM 會把存活的對象轉移到 Survivor 中,并且對象年齡 +1

    • 對象在 Survivor 中同樣也會經歷 Minor GC,每經歷一次 Minor GC,對象年齡都會+1

  4. 如果分配的對象超過了 -XX:PetenureSizeThreshold 直接被分配到老年代

內存的分配策略?

  • 對象優先在 Eden 分配: 大多數情況下,對象在新生代 Eden 上分配,當 Eden 空間不夠時,觸發 Minor GC

  • 大對象直接進入老年代: 當遇到一個較大的對象時,就算新生代的伊甸園為空,也無法容納該對象時,會將該對象直接晉升為老年代,最典型的大對象有長字符串和大數組。可以設置JVM參數 -XX:PretenureSizeThreshold ,大于此值的對象直接在老年代分配。

  • 長期存活的對象進入老年代: 通過參數 -XX:MaxTenuringThreshold 可以設置對象進入老年代的年齡閾值。對象在 Survivor 區每經過一次 Minor GC ,年齡就增加 1 歲,當它的年齡增加到一定程度,就會被晉升到老年代中。

  • 動態對象年齡判定: 并非對象的年齡必須達到 MaxTenuringThreshold 才能晉升老年代,如果在 Survivor 中相同年齡所有對象大小的總和大于 Survivor 空間的一半,則年齡大于或等于該年齡的對象可以直接進入老年代,無需達到 MaxTenuringThreshold 年齡閾值。

  • 空間分配擔保: 在發生 Minor GC 之前,虛擬機先檢查老年代最大可用的連續空間是否大于新生代所有對象總空間,如果條件成立的話,那么 Minor GC 是安全的。如果不成立的話虛擬機會查看HandlePromotionFailure 的值是否允許擔保失敗。如果允許,那么就會繼續檢查老年代最大可用的連續空間是否大于歷次晉升到老年代對象的平均大小,如果大于,將嘗試著進行一次 Minor GC,盡管這次Minor GC是有風險的;(也就是說,會把原先新生代的對象挪到老年代中) ;如果小于,或者 HandlePromotionFailure 的值為不允許擔保失敗,那么就要進行一次 Full GC 。

空間分配擔保時的 “冒險”是冒了什么風險?

新生代使用復制收集算法,但為了內存利用率,只使用其中一個Survivor空間來作為輪換備份,因此當出現大量對象在Minor GC后仍然存活的情況(最極端的情況就是內存回收后新生代中所有對象都存活),就需要老年代進行分配擔保,把Survivor無法容納的對象直接進入老年代。但前提是老年代本身還有容納這些對象的剩余空間,一共有多少對象會活下來在實際完成內存回收之前是無法明確知道的,所以只好取之前每一次回收晉升到老年代對象容量的平均大小值作為經驗值,與老年代的剩余空間進行比較,決定是否進行Full GC來讓老年代騰出更多空間。

取平均值進行比較其實仍然是一種動態概率的手段,也就是說,如果某次Minor GC存活后的對象突增,遠遠高于平均值的話,依然會導致擔保失敗(Handle Promotion Failure)。如果出現了HandlePromotionFailure失敗,那就只好在失敗后重新發起一次Full GC。雖然擔保失敗時繞的圈子是最大的,但大部分情況下都還是會將HandlePromotionFailure開關打開,避免Full GC過于頻繁。

Young GC的觸發條件

在Java 中,Young GC(Minor GC)是針對新生代(Young Generation)對象的垃圾回收。主要有三種情況會會觸發 Young GC:

  • Eden 區空間不足:新生代被劃分為三個區域,Eden區、S0(Survivor0)區和S1(Survivor 1)區,大部分新創建的對象會先分配到 Eden 區。當 Eden 區的對象填滿,無法再為新的對象分配空間時,Young GC 會被觸發,回收新生代中不再使用的對象。
  • Eden 區+Survivor 區都裝滿:如果 Eden 區和 Survivor 區的空間都不足以存放新分配的對象時,Young GC 也會被觸發,清理空間并將幸存的對象轉移到 Survivor 區或老年代
  • 部分垃圾回收器在 full gc 之前:有一些收集器的回收實現是在 full gc 前會讓先執行以下 young gc。比如 Parallel Scavenge,不過有參數可以調整讓其不進行 young gc。

Full GC 的觸發條件?

對于 Minor GC,其觸發條件非常簡單,當 Eden 空間滿時,就將觸發一次 Minor GC。而 Full GC 則相對復雜,有以下條件:?

  • 用 System.gc(): 只是建議虛擬機執行 Full GC,但是虛擬機不一定真正去執行。不建議使用這種方式,而是讓虛擬機管理內存。

  • 老年代空間不足: 老年代空間不足的常見場景為前文所講的大對象直接進入老年代、長期存活的對象進入老年代等。為了避免以上原因引起的 Full GC,應當盡量不要創建過大的對象以及數組、注意編碼規范避免內存泄露。除此之外,可以通過 -Xmn 參數調大新生代的大小,讓對象盡量在新生代被回收掉,不進入老年代。還可以通過 -XX:MaxTenuringThreshold 調大對象進入老年代的年齡,讓對象在新生代多存活一段時間。

  • 空間分配擔保失敗: 當程序創建一個大對象時,Eden區域放不下大對象,使用復制算法的 Minor GC 需要老年代的內存空間作擔保,如果擔保失敗會執行一次 Full GC。

  • JDK 1.7 及以前的永久代空間不足: 在 JDK 1.7 及以前,HotSpot 虛擬機中的方法區是用永久代實現的,永久代中存放的為一些 Class 的信息、常量、靜態變量等數據。當系統中要加載的類、反射的類和調用的方法較多時,永久代可能會被占滿,在未配置為采用 CMS GC 的情況下也會執行 Full GC。如果經過 Full GC 仍然回收不了,那么虛擬機會拋出 java.lang.OutOfMemoryError 。(JDK 8以后元空間不足

  • Concurrent Mode Failure:執行 CMS GC 的過程中同時有對象要放入老年代,而此時老年代空間不足(可能是 GC 過程中浮動垃圾過多導致暫時性的空間不足),便會報 Concurrent Mode Failure 錯誤,并觸發 Full GC。

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

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

相關文章

FDMA讀寫AXI BRAM交互:FPGA高速數據傳輸的核心技術

在圖像處理系統中,當1080P視頻流以每秒60幀的速度傳輸時,傳統DMA每幀會浪費27%的帶寬在地址管理上——而FDMA技術能將這些損失降至3%以內 現代FPGA系統中,高效數據搬運往往是性能瓶頸的關鍵所在。當你在手機上流暢播放4K視頻、在自動駕駛系統中實時處理激光雷達點云時,背后…

獨立開發A/B測試實用教程

A/B測試(A/B Testing),又稱分組測試、對照實驗,是產品開發和運營中提升轉化率、優化用戶體驗的常用方法。無論你是做App、SaaS、網站還是小程序,合理地利用A/B測試,都能幫助你用數據驅動決策,讓…

如何將iPhone備份到Mac/MacBook

許多iPhone用戶非常重視備份,但在Mac上選擇合適的備份方法可能會令人困惑。市場上有各種各樣的備份工具,找到一個既易于使用又能保存所有重要數據(如照片、視頻、消息、WhatsApp聊天記錄和聯系人)的工具至關重要。如果你正在尋找一…

Logseq 插件開發實戰四:發布到官方插件市場

🚩系列回顧 初識插件機制并實現自動壓縮粘貼的圖片國際化 I18N 與配置多語言自定義斜線命令 SlashCommand發布到官方插件市場 開源地址:logseq-plugin-image-tiny,歡迎來?。 🐞 插件上線問題記錄 問題描述 本地插件開發完成后…

[netty5: ByteToMessageCodec MessageToByteEncoder ByteToMessageDecoder]-源碼分析

ByteToMessageCodec ByteToMessageCodec 是一個結合了 ByteToMessageDecoder 和 MessageToByteEncoder 的編解碼器&#xff0c;可以實時地將字節流編碼或解碼為消息&#xff0c;反之亦然。 public abstract class ByteToMessageCodec<I> extends ChannelHandlerAdapter {…

Ubuntu20.04安裝mujoco210, mujoco-py時的報錯處理

參考 Ubantu 20.04 安裝 Mujoco210、mujoco-py、gym及報錯解決 安裝 mujoco210 創建 .mujoco 文件夾 mkdir ~/.mujoco親測必須是 .mujoco 文件夾&#xff0c;不然會報錯&#xff01; 下載 mujoco210-linux-x86_64.tar.gz 并解壓到 .mujoco 文件夾 mojoco下載地址 測試 mojo…

全志T507 音頻ALSA核心層注冊流程分析

一.ALSA核心層注冊流程分析 驅動目錄&#xff1a;kernel-4.9/sound/core/sound.c struct file_operations snd_fops {.owner THIS_MODULE,.open snd_open, (inode, file)---->struct snd_minor *mptr snd_minors[minor];---->file->f_op fops_get(mptr->f_ops…

評論區實現 前端Vue

根據后端部分定義評論區功能實現 golang后端部分-CSDN博客&#xff0c;重點需要實現三個部分&#xff0c;1.當前用戶發起新根評論請求&#xff1b;2.評論區展示部分&#xff1b;3.某一根評論的子評論展示以及回復組件顯示。 整體流程解釋 數據從后端接收&#xff0c;整體在in…

差分定位技術:原理、分類與應用場景

文章目錄 簡介基本概念位置差分偽距差分載波相位 差分定位技術精密單點定位&#xff08;PPP&#xff09;差分全球定位系統&#xff08;DGPS&#xff09;實時動態定位&#xff08;RTK&#xff09; 應用場景總結 簡介 差分定位&#xff08;Differential Positioning&#xff09;是…

tomcat的tar包轉換成rpm包的保姆級教程

環境說明 &#xff1a;centos 71. 安裝打包工具&#xff1a;yum install -y rpm-build rpmdevtools2. 創建 RPM 打包環境&#xff1a;rpmdev-setuptree?輸入之后是下面的結果~/rpmbuild/ ├── BUILD ├── RPMS ├── SOURCES ├── SPECS └── SRPMS?準備 Tomcat 源碼…

【牛客算法】小美的數組刪除

文章目錄 一、題目介紹二、解題思路三、解題算法實現四、算法分析4.1 代碼邏輯4.2 逆向遍歷求MEX的設計精妙之處4.2.1 逆向遍歷:解決MEX更新的連續性4.2.2 利用MEX的單調性4.2.3 空間復用與狀態壓縮4.2.4 與問題特性的完美契合4.2.5 總結:為什么說這個設計“妙”?五、算法復…

MyBatisPlus-01-環境初始化及簡單應用

文章目錄【README】【1】springboot集成mybatis-plus配置【1.1】目錄結構【相關說明】【1.2】代碼示例【pom.xml】【application.properties】【MybatisPlusNoteController】【UserAppService】【UserMapper】【UserPO】【建表語句】【2】演示【README】 本文代碼參見&#xf…

Web爬蟲編程語言選擇指南

剛學爬蟲的小伙伴常常為選擇那種語言來寫爬蟲而煩惱&#xff0c;今天我將總結幾種語言的優劣勢&#xff0c;然后選擇適合編寫 Web爬蟲 的編程語言。這就需要我們考慮開發效率、生態庫支持、并發性能等因素。以下是主流選擇及特點跟著一起看看吧&#xff1a; 1. Python&#xff…

學習日志06 python

加油&#xff0c;今天的任務是學習面向對象編程&#xff0c;設計一個簡單的寵物管理系統&#xff08;寵物類、貓 / 狗子類&#xff09;&#xff0c;先做5道題目開啟學習狀態吧&#xff01;1 setdefault()在 Python 中&#xff0c;setdefault() 是字典&#xff08;dict&#xff…

基于Java+springboot 的車險理賠信息管理系統

源碼、數據庫、包調試源碼編號&#xff1a;S595源碼名稱&#xff1a;基于springboot 的車險理賠信息管理系統用戶類型&#xff1a;多角色&#xff0c;用戶、事故調查員、管理員數據庫表數量&#xff1a;14 張表主要技術&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven運…

MyDockFinder 綠色便攜版 | 一鍵仿Mac桌面,非常簡單

如果你既不想升級到Win11&#xff0c;又想體驗Mac桌面的高級感&#xff0c;那么MyDockFinder將是你的最佳選擇。這是一款專為Windows系統設計的桌面美化工具&#xff0c;能夠將你的桌面轉變成MacOS的風格。它提供了類似Dock欄和Finder的功能&#xff0c;讓你在不更換操作系統的…

Babylon.js 材質克隆與紋理共享:你可能遇到的問題及解決方案

在 Babylon.js 中&#xff0c;材質&#xff08;Material&#xff09;和紋理&#xff08;Texture&#xff09;的克隆行為可能會影響渲染性能和內存管理&#xff0c;尤其是在多個材質共享同一紋理的情況下。本文將探討&#xff1a;PBRMetallicRoughnessMaterial 的克隆機制&#…

信息素養復賽模擬1和模擬2的編程題標程

信息素養復賽模擬 11&#xff1a;樓層編號 #include<bits/stdc.h> using namespace std; int main(){int n, t;cin >> n >> t;int res 0;for(int i 1; i < n; i ){int x i;bool ok true;while(x){if(x % 10 t){ok false;}x / 10;}res ok;} cout &l…

Hadoop高可用集群搭建

Hadoop高可用(HA)集群是企業級大數據平臺的核心基礎設施&#xff0c;通過多主節點冗余和自動故障轉移機制&#xff0c;確保系統在單點故障時仍能正常運行。本文將詳細介紹如何基于CentOS 7搭建Hadoop 3.X高可用集群&#xff0c;涵蓋環境準備、組件配置、集群啟動及管理的全流程…

Next.js 實戰筆記 1.0:架構重構與 App Router 核心機制詳解

Next.js 實戰筆記 1.0&#xff1a;架構重構與 App Router 核心機制詳解 上一次寫 Next 相關的東西都是 3 年前的事情了&#xff0c;這 3 年里 Next 也經歷了 2-3 次的大版本變化。當時寫的時候 Next 是 12 還是 13 的&#xff0c;現在已經是 15 了&#xff0c;從 build 到實現…