JVM垃圾回收面試題及原理

1. 對象什么時候可以被垃圾器回收

如果一個或多個對象沒有任何的引用指向它了,那么這個對象現在就是垃圾,如果定位了垃圾,則有可能會被垃圾回收器回收
在這里插入圖片描述

如果要定位什么是垃圾,有兩種方式來確定

  • 引用計數法
  • 可達性分析算法

1.1 引用計數法

1.1.1 原理

String demo = new String;

在這里插入圖片描述

String demo = null;

在這里插入圖片描述

1.1.2 局限

創建實例,互相調用

public class Demo {
Demo instance;
String name;
public Demo(String name)(
this.name = name;Demo a = new Demo"a");
Demo b = new Demo("b?);
a.instance = b;
b.instance = a

在這里插入圖片描述

設置a,b為null,互相引用導致ref=1,循環引用,會引發內存泄露

a = null;
b = null

在這里插入圖片描述

1.2 可達性分析算法

現在的虛擬機采用的都是通過可達性分析算法來確定哪些內容是垃圾。
在這里插入圖片描述

X,Y這兩個節點是可回收的

  • Java 虛擬機中的垃圾回收器采用可達性分析來探索所有存活的對象
  • 掃描堆中的對象,看是否能夠沿著GC Root 對象為起點的引用鏈找到該對象,找不到,表示可以回收

1.2.1 哪些對象可以作為GC Root

  • 虛以機棧(棧幀中的本地變量表)中引用的對象
public static void main (Stringll args) {
Demo demo = new Demo);
demo = null;
  • 方法區中類靜態屬性引用的對象
public static Demo a;
public static void main(Stringl] args) {
Demo b = new Demo);
b.a = new Demo;
b = null;
  • 方法區中常量引用的對象
public static final Demo a = new Demo);
public static void main(String[] args) {
Demo demo = new Demo;
demo = null;
  • 本地方法棧中JNI(即一般說的Native 方法)引用的對象

2. 垃圾回收算法

2.1 標記清除算法

2.1.1 原理

標記清除算法,是將垃圾回收分為2個階段,分別是標記和清除。

  1. 根據可達性分析算法得出的垃圾進行標記
  2. 對這些標記為可回收的內容進行垃圾回收
    在這里插入圖片描述

2.1.2 局限

  • 優點:標記和清除速度較快
  • 缺點:碎片化較為嚴重,內存不連貫的
    內存分配碎片化對數組存儲不友好(數組占用連續的儲存空間,難存儲大數組)

2.2 標記整理算法

優缺點同標記清除算法,解決了標記清除算法的碎片化的問題,同時,標記壓縮算法多了一步,對象移動內存位置的步驟其效率也有有一定的影響
在這里插入圖片描述

2.3 復制算法

  • 優點:
    1. 在垃圾對象多的情況下,效率較高
    2. 清理后,內存無碎片
  • 缺點:
    1. 分配的2塊內存空間,在同一個時刻,只能使用一半,內存使用率較低(一般新生代的垃圾回收器會用復制算法)
      在這里插入圖片描述

3. JVM中的分代回收

在java8時,堆被分為了兩份:新生代和老年代(數量1:2)
對于新生代,內部又被分為了三個區域。

  • 伊甸園區Eden,新生的對象都分配到這里
  • 幸存者區survivor(分成from和to)
  • Eden區, from區, to區(8: 1: 1)
    在這里插入圖片描述

3.1 工作機制

  • 新創建的對象,都會先分配到eden區
  • 當伊甸園內存不足,標記伊甸園與from(現階段沒有)的存活對象
  • 將存活對象采用復制算法復制到 to 中,復制完畢后,伊甸園和 from 內存都得到釋放
  • 經過一段時間后伊甸園的內存又出現不足,標記eden區域to區存活的對象,將存活的對象復制到from區
  • 當幸存區對象熬過幾次回收(最多15次),晉升到老年代(幸存區內存不足或大對象會導致提前晉升)

3.2 MinorGC、 Mixed GC、 FullGC的區別

STW(Stop-The-World):暫停所有應用程序線程,等待垃圾回收的完成

  • MinorGC【young GC】發生在新生代的垃圾回收,暫停時間短(STW)
  • Mixed GC新生代+老年代部分區域的垃圾回收,G1 收集器特有
  • FulIGC:新生代+老年代完整垃圾回收,暫停時間長(STW),應盡力避免(只有新生代和老年代內存完全不足的時候)

4. 垃圾回收器

在jvm中,實現了多種垃圾收集器,包括:

  • 串行垃圾收集器
  • 并行垃圾收集器
  • CMS(并發)垃圾收集器
  • G1垃圾收集器

4.1 串行垃圾收集器

Serial和Serial Old串行垃圾收集器,是指使用單線程進行垃圾回收,堆內存較小,適合個人電腦

  • Serial 作用于新生代,采用復制算法
  • Serial Old 作用于老年代,采用標記-整理算法
    垃圾回收時,只有一個線程在工作,并且java應用中的所有線程都要暫停(STW),等待垃圾回收的完成。
    在這里插入圖片描述

4.2 并行垃圾收集器

Parallel New和Parallel Old是一個并行垃圾回收器,JDK8默認使用此垃圾回收器

  • Parallel New作用于新生代,采用復制算法
  • Parallel Old作用于老年代,采用標記-整理算法
    垃圾回收時,多個線程在工作,并且java應用中的所有線程都要暫停(STW),等待垃圾回收的完成。
    在這里插入圖片描述

4.3 CMS(并發)垃圾收集器

CMS全稱 Concurrent Mark Sweep,是一款并發的、使用標記-清除算法的垃圾回收器,該回收器是針對老年代垃圾回收的,是一款以獲取最短回收停頓時間為目標的收集器,停頓時間短,用戶體驗就好。其最大特點是在進行垃圾回收時,應用仍然能正常運行。
在這里插入圖片描述

初始標記是GC Roots連接的,并發標記是下面所有的節點。
重新標記(像檢查是否有錯題)是檢測是否有新連接的或有新垃圾節點出現。
在這里插入圖片描述

4.4 G1垃圾收集器

應用于新生代和老年代,在JDK9之后默認使用G1

  • 應用于新生代和老年代,在JDK9之后默認使用G1
  • 劃分成多個區域,每個區域都可以充當 eden,survivor, old,humongous(其中 humongous 專為大對象準備)
  • 采用復制算法
  • 響應時間與吞吐量兼顧
  • 分成三個階段:新生代回收、并發標記、混合收集
  • 如果并發失敗(即回收速度趕不上創建新對象速度),會觸發 Full GC
    在這里插入圖片描述

4.4.1 Young Collection(年輕代垃圾回收)

  • 隨著時間流逝,伊甸園的內存又有不足
  • 將伊甸園以及之前幸存區中的存活對象,采用復制算法,復制到新的幸存區,其中較老對象晉升至老年代
    在這里插入圖片描述

4.4.2 Young Collection + Concurrent Mark(年輕代垃圾回收+并發標記)

當老年代占用內存超過閾值(默認是45%)后,觸發并發標記,這時無需暫停用戶線程
在這里插入圖片描述

  • 并發標記之后,會有重新標記階段解決漏標問題,此時需要暫停用戶線程。
  • 這些都完成后就知道了老年代有哪些存活對象,隨后進入混合收集階段。此時不會對所有老年代區域進行回收,而是根據暫停時間目標優先回收價值高(存活對象少)的區域(這也是 Gabage First 名稱的由來)

4.4.3 Mixed Collection(混合垃圾回收)

混合收集階段中,參與復制的有 eden、survivor、old
在這里插入圖片描述

復制完成,內存得到釋放。進入下一輪的新生代回收、并發標記、混合收集

5. 強引用、軟引用、弱引用、虛引用的區別

5.1 強引用

只有所有 GC Roots 對象都不通過【強引用】引用該對象,該對象才能被垃圾回收
內存溢出OOM也不會垃圾回收強引用的對象。

String user = new User();

在這里插入圖片描述

5.2 軟引用

僅有軟引用引用該對象時,在垃圾回收后,內存仍不足時會再次出發垃圾回收

User user = new User();
SoftReference softReference = new SoftReference (user);

在這里插入圖片描述

5.3 弱引用

僅有弱引用引用該對象時,在垃圾回收時,無論內存是否充足,都會回收弱引用對象

User user = new User);
WeakReference weakReference = new WeakReference(user);

在這里插入圖片描述

5.4 虛引用

必須配合引用隊列使用,被引用對象回收時,會將虛引用入隊,由 Reference Handler 線程調用虛引用相關方法釋放直接內存

User user = new User();
ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference phantomReference = new PhantomReference (user, queue);

在這里插入圖片描述

除了釋放user對象,還要釋放虛引用對象所關聯的一些外部資源——可能是一些外部資源(不是java占用的、也不是java內存,可能是直接內存等…),這些等java對象被回收掉后再釋放。所以要把虛擬對象先記錄在引用隊列中,先記住被回收的對象,后面直接找隊列就可以了(釋放的時候有專門的線程:Reference Handler)

  • 軟引用和弱引用也可以通過引用隊列釋放相關資源

5.5 區別

  • 強引用:只要所有 GC Roots 能找到,就不會被回收
  • 軟引用:需要配合SofiReference使用,當垃圾多次回收,內存依然不夠的時候會回收軟引用對象
  • 弱引用:需要配合WeakReference使用,只要進行了垃圾回收,就會把弱引用對象回收
  • 虛引用:必須配合引用隊列使用,被引用對象回收時,會將虛引用入隊,由 Reference Handler 線程調用虛引用相關方法釋放直接內存

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

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

相關文章

《Mycat核心技術》第19章:基于MySQL實現讀寫分離

作者:冰河 星球:http://m6z.cn/6aeFbs 博客:https://binghe.gitcode.host 文章匯總:https://binghe.gitcode.host/md/all/all.html 星球項目地址:https://binghe.gitcode.host/md/zsxq/introduce.html 沉淀&#xff0c…

【安卓逆向】安卓病毒介紹及其簡單案例分析

目錄 引言 一、Android 病毒介紹及分析方法 1.1 Android 病毒預覽 1.2 Android 病毒分析必備知識 1.3 Android 病毒的常見類型及惡意行為 1.3.1 常見病毒類型 1.3.2 常見病毒行為 1.4 病毒激活條件 1.5 Android 病毒的傳播方式 1.6 Android 病毒分析的一般方法 二…

基于LabVIEW的腳本化子VI動態生成

該示例展示了一種利用LabVIEW VI腳本(VI Scripting)技術,通過程序化方式動態生成并替換子VI的解決方案。核心邏輯為:基于預定義的模板VI,根據用戶選擇的數學操作(加法或乘法),自動生…

機器學習之超參數優化(Hyperparameter Optimization)

超參數優化(Hyperparameter Optimization) 1. 簡介 在機器學習和深度學習中,超參數(Hyperparameters) 是在訓練之前需要設定的參數,例如學習率(learning rate)、批量大小(batch size)、神經網絡的層數等。與訓練過程中自動學習的模型參數(如權重和偏置)不同,超參…

Manus 演示案例:谷歌公司運營模擬器游戲體驗

一、項目背景與愿景 在科技行業蓬勃發展的當下,谷歌作為行業巨頭,其成長歷程充滿了無數值得深入探究的決策智慧。這些決策不僅塑造了谷歌的輝煌,也為全球企業的發展提供了寶貴的借鑒。本項目旨在打造一款以谷歌公司發展為藍本的運營模擬器游戲…

es-索引詳解

在 Elasticsearch 中,**索引(Index)**是核心概念之一,類似于關系型數據庫中的“表”。索引用于存儲、組織和檢索文檔(Document)。以下是關于 Elasticsearch 索引的詳細解析: 1. 索引的基本概念 …

基于策略模式的智能提示語生成器設計與實現——以Tkinter GUI開發為例

基于策略模式的智能提示語生成器設計與實現——以Tkinter GUI開發為例 一、引言:智能化時代的提示工程工具 在人工智能技術廣泛應用的時代背景下,如何與AI模型進行有效交互已成為關鍵技能。本文介紹的"AI任務需求與提示語策略生成器"正是基于…

01 | Go 項目開發極速入門課介紹

提示: 所有體系課見專欄:Go 項目開發極速入門實戰課。 你好,歡迎學習本課程。本課程是一個 Go 項目開發極速入門課程。旨在幫助剛學習完 Go 基礎語法的 Go 開發者,快速掌握如何開發一個功能相對全面的 Go 項目。 根據課程設計目標…

密閉空間可燃氣體監測終端:守護城市命脈,智馭燃氣安全!

近年來,陜西省高度重視燃氣安全,出臺了一系列政策文件,旨在全面加強城鎮燃氣安全監管,防范化解重大安全風險。2023年,陜西省安委會印發《全省城鎮燃氣安全專項整治工作方案》,明確要求聚焦燃氣經營、輸送配…

大白話react第十八章React 與 WebGL 項目的高級拓展與優化

大白話react第十八章React 與 WebGL 項目的高級拓展與優化 1. 實現 3D 模型的導入與動畫 在之前的基礎上,我們可以導入更復雜的 3D 模型,并且讓這些模型動起來,就像在游戲里看到的角色和場景一樣。這里我們使用 GLTF 格式的模型&#xff0c…

有關Java中的多線程

學習目標 ● 掌握線程相關概念 ● 掌握線程的基本使用 ● 掌握線程池的使用 ● 了解解決線程安全方式 1.為什么要學習線程? ● 從1946年2月14日世界上第一臺計算機在美國賓夕法尼亞大學誕生到今天,計算和處理的模式早已從單用戶單任務的串行模式發展到了多用戶多…

Spring Boot集成EasyExcel

1. 初始化Spring Boot項目 首先,使用Spring Initializr(https://start.spring.io/)生成一個基本的Spring Boot項目。選擇以下依賴項: Spring WebLombok (用于減少樣板代碼)SLF4J (用于日志記錄) 2. 添加依賴 在你的pom.xml文件…

(2025|ICLR|廈大華為,LoSA,基于表示互信息的動態層級稀疏率,基于重構誤差的秩分配)LLM 的動態低秩稀疏自適應

Dynamic Low-Rank Sparse Adaptation for Large Language Models 目錄 1. 引言 1.1 關鍵詞 2. 方法 2.1 預備知識 2.2 層級稀疏率確定 2.3 稀疏感知的秩分配 2.4 動態稀疏與適配 3. 實驗 3.1 實驗設置 3.2 語言建模 3.3 零樣本任務 3.4 N:M 稀疏性 3.5 消融實驗 …

p5.js:sound(音樂)可視化,動畫顯示音頻高低變化

本文通過4個案例介紹了使用 p5.js 進行音樂可視化的實踐,包括將音頻振幅轉化為圖形、生成波形圖。 承上一篇:vite:初學 p5.js demo 畫圓圈 cd p5-demo copy .\node_modules\p5\lib\p5.min.js . copy .\node_modules\p5\lib\addons\p5.soun…

linux 進程和計劃管理

查看進程 在Linux系統中,有多個命令可以用來查看進程 以下是一些常用的命令: ps命令:用于查看當前系統中的進程狀態。 基本用法:ps -ef,該命令會以完整格式顯示所有進程的詳細信息,包括用戶ID、進程ID、父…

DeepSeek 多模態大模型 Janus-Pro 本地部署教程

下載模型倉庫 git clone https://github.com/deepseek-ai/Janus.git 國內下載倉庫失敗時,可以使用以下代理: git clone https://github.moeyy.xyz/https://github.com/deepseek-ai/Janus.git 準備 Conda 3.12 虛擬環境 conda create --name deepseek7B p…

Qt開源控件庫(qt-material-widgets)的編譯及使用

項目簡介 qt-material-widgets是一個基于 Qt 小部件的 Material Design 規范實現。 項目地址 項目地址:qt-material-widgets 本地構建環境 Win11 家庭中文版 VS2019 Qt5.15.2 (MSVC2019) 本地構建流程 克隆后的目錄結構如圖: 直接使用Qt Crea…

ARM 嵌入式處理器內核與架構深度剖析(2): ARM 處理器架構剖析

目錄 一、ARM處理器架構剖析 1.1. 指令集架構(ISA) 1.2. 寄存器集 1.3. 存儲模型 1.4. 異常模型 二、架構設計精要 2.1 處理器模式與特權分級 2.2 寄存器銀行化技術 2.3 指令集演化 三、微架構核心技術 3.1 流水線創新 3.2 內存子系統 3.3 …

Flutter 按鈕組件 TextButton 詳解

目錄 1. 引言 2. TextButton 的基本用法 3. 主要屬性 4. 自定義按鈕樣式 4.1 修改文本顏色 4.2 添加背景色 4.3 修改按鈕形狀和邊距 4.4 樣式定制 5. 高級應用技巧 5.1 圖標文本組合 5.2 主題統一配置 5.3 動態交互 6. 性能優化與注意事項 6.1 點擊區域優化 6.…

std::ranges::views::split, lazy_split, std::ranges::split_view, lazy_split_view

std::ranges::views::split, std::ranges::split_view C20 中引入的用于分割范圍(range)的組件,允許將輸入范圍按特定分隔符或條件分割成多個子范圍。以下是詳細說明和示例: 基本概念 1. 功能 分割范圍:將輸入范圍&…