深入解析JVM內存結構與垃圾回收機制

java是強類型高級語言
JVM(Java Virtual Machine,Java虛擬機)是Java平臺的核心組件,它是一個虛擬的計算機,能夠執行Java字節碼(bytecode)。

1、區域劃分

JVM對Java內存的管理也是分區分塊進行,方便管理。

這一部分稱之為
運行時數據區域
這個區域也可以進行細分
區域a:線程私有,對別的線程不可見
????????棧——存儲方法調用和局部變量
????????????????本地方法棧——用于本地方法的存儲,本質上和虛擬機棧沒有 區別(很多虛擬機都將二者一起管理)
????????本地方法(Native Method) 是指由非 Java 語言(如 C、C++ 等)實現,并通過 Java 虛擬機(JVM)調用的方法。它的作用是讓 Java 代碼能夠與底層系統或硬件交互,彌補 Java 語言在性能或系統級操作上的局限性。
????????????????虛擬機棧——存儲方法的局部變量,出口等一系列數據(棧幀)
程序計數器——指向線程正在執行的字節碼行號(唯一不會發生OOM(OutOfMemoryError)的區域
區域b:線程共享
????????方法區——類信息,常量,靜態變量,JDK 8后由元空間(Metaspace)實現,使用本地內存
運行時常量池:方法區的一部分,存放編譯期生成的各種字面量和符號引用
????????堆(最大)——為對象和數組分配內存的地方,CG主要管理的區域

2、對象的組成

創建對象和銷毀對象的過程是什么
2.1 分配內存給對象的方式
都采用循環CAS策略進行并發情況下的差錯避免
假如內存是規整的:指針碰撞,移動指針分配空間即可,但當某塊內存被回收后需要對當前內存進行整理
假如內存是不規整:建立空閑列表,需要挑選一個合適大小的空間分配,但會出現大量的空間碎片
TLAB:考慮到對象的創建是一個十分頻繁的內容,指針爭奪和CAS要大量進行,所以每個線程提前分配一塊內存,以減少爭奪指針的次數,這個叫本地線程分配緩存(Thread Local Allocation Buffer,TLAB),分配后初始化為零值。
2.2 對象的內存布局
對象頭
MarkWord標記字——存儲對象信息,是一個動態定義的數據結構。會有不同的標志位,不同標志位代表后續存儲的內容不同
指向對象類型的指針——表明對象類型
如果對象是數組時,會額外存儲數組長度
實例數據
private string name等的和對象相關信息,就是實例數據。可以存基本類型也可以存地址指針。
對齊填充
填充到要求大小
2.3對象的訪問方式
我們的Java程序會通過棧上的reference數據來操作堆上的具體對象。
使用句柄
reference中存儲的就是對象的句柄地址,句柄中包含了對象實例數據與類型數據各自具體的地址信息,棧——>句柄池——>實例池&方法區
直接指針
reference中存儲的直接就是對象地址,棧——>堆——>方法區
  • 使用句柄來訪問的最大好處就是reference中存儲的是穩定句柄地址,對象位置發生移動時,只需要修改句柄地址,不需要修改reference
  • 直接指針來訪問最大的好處就是速度更快,它節省了一次指針定位的時間開銷,但在大量訪問的情況下這個好處可以被忽略

3.垃圾收集

3.1 哪些是垃圾?
判斷生死
腦門刻字法(引用計數法):引用指向該對象——>計數+1
引用斷開指向該對象——>計數-1,為0就回收,但單純的引用計數就很難解決對象之間相互循環引用的問題。
平地長樹法(可達性分析):現行虛擬機使用的主要方式。從CGRoot開始向下搜索,不可達的對象被判定為可回收對象。
GC Roots的對象包括以下幾種:虛擬機棧中的對象、方法區靜態屬性引用的對象、方法區常量引用的對象、本地方法棧引用的對象、虛擬機內部對象、同步鎖持有的對象,還有一些會被臨時加入
引用類型
????????強引用:在代碼中普遍存在的引用賦值
????????軟引用:還有用但非必須可以作為緩存使用
????????弱引用:可以作為緩存,被下一次垃圾回收回收
????????虛引用
3.2 怎樣回收?
分代收集理論
JVM會把性質類似的對象放在一起集中管理
弱分代假說
????????不需要分代,因為大部分對象死的都很快
強分代假說
????????需要分代,獲得時間越長的對象越傾向于活下去
把Java堆劃分為不同的區域,回收對象根據年齡劃分:新生代、老年代。
新生代的回收頻率要高于老年代。
跨代引用假說
????????相對于同代引用僅占極少數。新生代引用老年代。老年代引用新生代。這種情況下會在被老年代引用的新生代上做標記(記憶集),標記出該新生代被哪個老年代的區域引用,此時把老年代的那一內存小塊放入CGRoot中進行掃描(CGRoot的特殊部分
3.3 收集算法
標記-清除算法
????????算法簡單,但缺點明顯:空間碎片問題,stop the world問題這要求用戶線程完全停止。
空間碎片化的解決方式:
標記-復制算法
? ? ? ? ?劃分為AB區域,左右復制刪除清空,僅適用于收集效率高的場合(朝生夕死),并且只有一半的有效空間。(適用于新生代
????????標記復制優化——劃分為三個區域:Eden區(8)Survivor區(From/To)(1)
標記-整理算法
????????把存活的部分集中在前部,清除后部分的。沒有空間碎片,但是需要移動對象
3.4 HotSpot算法實現細節
根節點枚舉
我們通過OopMap來實現根節點枚舉,讓虛擬機在掃描時就直接得到根節點的信息,它的核心作用是讓垃圾回收器快速準確地識別棧和寄存器中哪些位置包含指向對象的引用(即 "對象指針")。
遍歷oopmap即可搜集到根節點
安全點
OopMap 與安全點緊密相關,安全點是程序執行過程中可以暫停并執行 GC 的位置,每個安全點都關聯一個 OopMap。
安全點位置的選取基本上是以“是否具有讓程序長時間執行的特征”為標準進行選定的。(方法調用,循環跳轉,異常跳轉等指令序列復用
如何在垃圾收集時,讓所有線程都跑到安全點?
搶占式中斷-先中斷所有線程,不能中斷時恢復。不好
主動式中斷-借助標志
安全區域
安全區域是指能夠確保在某一段代碼片段之中,引用關系不會發生變化,因此,在這個區域中任意地方開始垃圾收集都是安全的。
記憶集與卡表
記憶集:所有涉及部分區域收集行為的垃圾收集器中,用于記錄從非收集區域指向收集區域的指針集合的抽象數據結構
記憶集有三種精度:字長精度、對象精度、卡精度
卡精度——卡表實現,卡頁內存有跨代指針,標志位置1,此時該卡表”變臟“,只需遍歷變臟卡頁就可得到區域。
寫屏障
HotSpot通過寫屏障維護卡表狀態。這是對引用對象賦值的一個環形通知(細分為寫前、寫后屏障)
3.5并發的可達性分析
基于一個保持一次性快照——對象引用關系不可改變
三色標記:
????????黑:已經被垃圾收集器放問過,且所有引用已經被掃描
????????白:尚未被標記
????????灰:已經被垃圾收集器放問過,且有引用未被掃描
????????由于這個過程會和用戶進程并發進行,此時會有浮動垃圾的產生和引用被誤刪的情況:當同時滿足 1 賦值器插入了一條或多條從黑色對象到白色對象的新引用,2 賦值器刪除了全部從灰色對象到該白色對象的直接和間接引用
解決方案:
????????增量更新:破壞1
????????原始快照:破壞2
3.6常見的收集器
Serial收集器
????????新生代標記-復制,老年代標記-整理
ParNew收集器
????????是Serial收集器并發版本。新生代標記-復制,老年代標記-整理
Parallel Scavenge收集器
????????標記-復制法目標是達到一個可控制的吞吐量
Serial Old收集器
????????標記-整理法。它作為CMS發生失敗的后備預案,在并發收集發生Concurrent Mode Failure時使用
Parallel Old收集器
????????標記-整理算法
CMS(Concurrent Mark Sweep)收集器
????????是一種以獲取最短回收停頓時間為目標的收集器。基于標記-清除算法實現,整個過程分為四個階段
????????初始標記(stop the world)標記直接關聯到的對象,速度很快
????????并發標記 遍歷整個路徑,但可以并發運行
????????重新標記(stop the world)
????????并發清除 也可以并發運行
其中耗時最長的并發標記和并發清除階段
有三個明顯的缺點:
  1. CMS對處理器資源非常敏感
  2. 由于CMS收集器無法處理“浮動垃圾”(產生于標記結束后的垃圾)
  3. CMS運行期間預留內存無法滿足新對象分配需要(啟動閾值為92%)
  4. 產生空間碎片
GI收集器(Garbage First)
????????是一種主要面向服務端應用的垃圾收集器。收集器面向局部收集的設計思路和基于Region的內存布局形式。
????????目標是:支持一個在長度為M毫秒的時間段內,花在垃圾收集上的時間不超過N毫秒。
基于Region幫助實現這個目標,把Java內存劃分為多個大小相等的區域,采用MixedGC模式,使回收收益最大
????????內存碎片問題不嚴重,但內存負載較高
3.7低延遲垃圾收集器
衡量垃圾收集器的三項最重要的指標是:
????????內存占用(Footprint)
????????吞吐量(Throughput)
????????延遲(Latency)
3.8內存分配與回收策略
  • 對象優先在Eden區
  • 大對象直接進老年代
  • 長期存活對象將進入老年代:對象年齡計數器(對象頭)
  • 動態年齡判定:動態調整進入老年代的年齡限制
  • 空間分配擔保:判斷老年代空間是否滿足新生代晉升(與歷史平均值對比)

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

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

相關文章

Java 流程控制詳解:從順序執行到跳轉語句,掌握程序邏輯設計

作為一名Java開發工程師,你一定知道,流程控制(Flow Control) 是編寫任何程序的核心。它決定了代碼的執行路徑、分支走向和循環次數。本文將帶你系統梳理 Java中的所有常用流程控制結構,包括:順序結構分支結…

面試150 環形鏈表

思路 采用雙指針法,slow指針每次走一步,fast指針每次走兩步,如果相遇的情況下,slow指針回到開始的位置,此時快慢指針各走一步,當相遇的時候也就是說明鏈表中有環。 # Definition for singly-linked list. # class ListNode: # def __init…

AI技術正在深度重構全球產業格局,其影響已超越工具屬性,演變為推動行業變革的核心引擎。

一、AI如何重塑AI的工作與行業(AI助手領域)能力升級理解與生成:基于LLM(大語言模型),AI能處理開放式問題、撰寫報告、翻譯代碼,替代部分人類知識工作。個性化交互:通過用戶歷史對話分…

Kafka的無消息丟失配置怎么實現

那 Kafka 到底在什么情況下才能保證消息不丟失呢? Kafka 只對“已提交”的消息(committed message)做有限度的持久化保證。 第一個核心要素是“已提交的消息”。什么是已提交的消息?當 Kafka 的若干個 Broker 成 功地接收到一條…

集成CommitLInt+ESLint+Prettier+StyleLint+LintStaged

代碼可讀性低代碼 代碼規范落地難代碼格式難統一代碼質量低下 配置 ESLint ESLint 是一個用來識別 ECMAScript 并且按照規則給出報告的代碼檢測工具,使用它可以避免低級錯誤和統一代碼的風格。它擁有以下功能: 查出 JavaScript 代碼語法問題。根據配置…

尋找兩個正序數組的中位數(C++)

給定兩個大小分別為 m 和 n 的正序(從小到大)數組 nums1 和 nums2。請你找出并返回這兩個正序數組的 中位數 。算法的時間復雜度應該為 O(log (mn)) 。示例 1:輸入:nums1 [1,3], nums2 [2] 輸出:2.00000 解釋&#x…

Expected Sarsa 算法的數學原理

🌟 一、Expected Sarsa 算法的數學原理 1. 什么是 Expected Sarsa? Expected Sarsa 是一種基于 時序差分(Temporal Difference, TD)學習 的強化學習算法,用于估計 動作值函數 ( q_{\pi}(s, a) )。它是 Sarsa 算法的一種…

Vue的watch和React的useEffect

參考文章:https://zhuanlan.zhihu.com/p/686329898

idea中合并git分支

1.把本地dev代碼合并到本地master代碼在提交代碼之前,先確保dev和master都拉取了最新的代碼都進行了Git->pull了這時候確保Local的第一個分支是master分支,然后選擇dev分支 ,鼠標右鍵-》Merge dev into master這時候會提示 有合并到本地master最新的代…

《Spring 中上下文傳遞的那些事兒》Part 7:異步任務上下文丟失問題詳解

📝 Part 7:異步任務上下文丟失問題詳解 在現代 Java 應用中,異步編程已經成為提升性能、解耦業務邏輯的重要手段。無論是使用 CompletableFuture、線程池(ExecutorService)、定時任務(ScheduledExecutorSe…

大語言模型驅動智能語音應答:技術演進與架構革新

在智能客服、電話銀行等場景中,用戶時常遇到這樣的困境:“請描述您的問題...抱歉沒聽清,請重試...正在為您轉接人工”。傳統語音應答(IVR)系統受限于規則引擎與淺層語義理解,難以應對復雜多變的自然語言表達…

【Linux】內存管理

要求:1、編寫程序,實現如下功能。(1)隨機生成 1000000 個 0~1 之間的數;(2)統計分析這些數據,計算均值、方差和分布情況,分布情況按0.01 的步長進行統計;&…

蒼穹外賣—day1

文章目錄前言一、接口文檔導入與生成二、前端環境搭建三、后端環境搭建1. 了解項目結構2. 環境搭建常見問題總結前言 (簡要說明筆記的目的:記錄搭建過程、關鍵配置和結構理解) 一、接口文檔導入與生成 Apifox 導入 使用工具:https…

基于微信小程序的在線疫苗預約小程序源碼+論文

基于微信小程序的在線疫苗預約系統源碼論文代碼可以查看文章末尾??聯系方式獲取,記得注明來意哦~🌹 分享萬套開題報告任務書答辯PPT模板 作者完整代碼目錄供你選擇: 《SpringBoot網站項目》800套 《SSM網站項目》1200套 《小程序項目》600套…

Windows 11 安裝過程中跳過微軟賬戶創建本地賬戶

背景 在 Windows 11 的安裝和設置過程中,Microsoft 賬號登錄是默認的認證方式。然而,在某些情況下,可能需要繞過此步驟以創建本地賬戶。 微軟在 2025 年 3 月推送的 Windows 11 預覽版(Build 26120.3653 和 Build 26200.5516&am…

利用DBeaver實現異構數據庫數據定時任務同步

1、背景 本需求需要實現抽取KingBaseEs數據庫的某幾張表數據,定時同步到MySQL中 2、工具準備 2.1 DBeaverEE25.1(必須要企業版,如果用社區版沒有定時任務功能) https://dbeaver.io/download/ 2.2 KingBaseEs數據庫及驅動 https://www.kingbase.com…

【TCP/IP】1. 概述

1. 概述1. 概述1.1 因特網及技術催生新時代1.1.1 信息化時代1.1.2 關鍵技術1.1.3 國家戰略1.2 網絡互聯的動機和技術1.2.1 網絡互聯的動機1.2.2 網絡互聯技術1.3 因特網的形成和發展1.3.1 國際因特網發展軌跡1.3.2 中國互聯網發展1.4 有關因特網的組織機構1.5 請求注解&#xf…

中老年人的陪伴,貓咪與機器人玩具有什么區別?

在人口結構深度老齡化的背景下,中老年群體的精神需求與情感陪伴已成為重要的社會議題。貓咪作為活生生的伴侶動物,與日新月異的智能陪伴機器人,代表了兩種截然不同的情感慰藉路徑——前者承載著生命互動的溫度與責任,后者則彰顯了…

day11-微服務面試篇

微服務在面試時被問到的內容相對較少,常見的面試題如下:SpringCloud有哪些常用組件?分別是什么作用?服務注冊發現的基本流程是怎樣的?Eureka和Nacos有哪些區別?Nacos的分級存儲模型是什么意思?R…

昇騰 k8s vnpu配置

參考文檔: https://www.hiascend.com/document/detail/zh/mindx-dl/500/AVI/cpaug/cpaug_018.html 此文檔實現為NPU910B3卡 主機設置靜態虛擬npu 設置虛擬化模式 !本命令只支持再物理機執行,取值為0或1,(如果是在虛擬機內劃分vNPU…