【Java】JVM虛擬機(java內存模型、GC垃圾回收)

一、Java內存模型(JMM)

????????JMM(Java Memory Model,Java 內存模型)是 Java 虛擬機規范中定義的一種抽象概念,用于規范 Java 程序中多線程對共享內存的訪問規則,解決可見性、原子性和有序性問題,確保 Java 程序在不同硬件和操作系統上都能獲得一致的并發行為。

運行時數據區劃分

? ? ? ? 線程私有:程序計數器、本地方法棧、虛擬機棧

????????線程公有:堆、元空間

程序計數器

? ? ? ? 字節碼解釋器在解釋執行字節碼文件工作時,當需要需要執行一條字節碼指令時,可以通過改變程序計數器的值來完成。

虛擬機棧

? ? ? ? 虛擬機棧是由一個個棧幀組成,而每個棧幀中都有:局部變量、操作數棧、動態鏈接、方法出口信息。每個方法調用時都會入棧,每個方法被調用結束后則會出棧,這樣可以清楚的看出方法之間的調用關系。

本地方法棧

? ? ? ? native關鍵字修飾的本地方法被執行時候,在本地方法棧中創建一個棧幀,用于存放發native本地方法的局部變量、操作數棧、動態鏈接、方法出口信息。方法執行完畢后,棧幀會釋放空間。

堆(Heap)

? ? ? ? 用于存放對象實例和數組的內存區域。

1、新生代、老年代

? ? ? ? 由于垃圾回收的需要,避免頻繁GC所以將堆分為新生代和老年代,其中新生代占1/3,老年代占2/3。而新生代又被分為EdenSurvivor區(from、to),占比為8:1:1。

2、對象創建時的內存分配

? ? ? ? 當創建一個新對象時會先看Eden區有沒有空間進行存儲,若沒有則執行YGC,執行后若還不能放下則看老年區是否可以放下,如果老年區不能放下,則執行老年區的FGC,執行后如果還不能不能放下,則會拋出OOM異常。

二、GC垃圾回收器

判讀對象是否存活

1、引用計數算法

? ? ? ? 在對象中添加一個引用計數器,如果對象被引用則+1,如果失去引用則-1,當我們需要判斷對象是否存活時,只需看該計算器的值是否為0。該方法不用于java中。

? ? ? ? 缺點:可能會出現循環引用的情況,從而出現死鎖。也就是a引用了b,b也引用了a。

2、可達性分析算法

? ? ? ? 通過定義一系列的" GC Roots "的根結點來作為開始結點集,當需要判斷對象是否存活時,則從根結點向下遍歷,沒有被遍歷到的則是可以被回收的垃圾對象。該方法用于java中。

3、java中四種引用類型

  • 強引用

????????最常見的引用類型,直接通過?new?關鍵字創建的對象引用。

// 強引用
Object object = new Object();

? ? ? ? 強引用它永遠不會被GC回收,當我們需要他被回收時,我們可以對其進行弱化。

// 弱化
object = null;
  • 軟引用

? ? ? ? 該引用類型可以根據內存的大小來判斷是否進行GC回收,當內存充足時不進行回收,當內存不足時進行回收。

// 軟引用
SoftReference<Object> softRef = new SoftReference<>(new Object());
Object obj = softRef.get();  // 獲取軟引用指向的對象
  • 弱引用

???????? 該引用類型無論是否內存充足只要發生GC就會被回收。例如:ThreadLocal中應用了弱引用

如果不使用對象后沒有及時進行銷毀,當發生GC時就會出現大量的null-value的鍵值對,從而導致發生OOM。

// 弱引用
WeakReference<Object> weakRef = new WeakReference<>(new Object());
Object obj = weakRef.get();  // 獲取弱引用指向的對象
  • 虛引用

? ? ? ? 虛引用主要用來跟蹤對象被垃圾回收的活動,可以在垃圾收集時收到一個系統通知。

// 虛引用
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), queue);

垃圾回收算法


復制算法

????????將內存空間劃分為?兩個相等的區域(如 From 空間和 To 空間),每次只使用其中一個區域:

  1. 當該區域內存用完時,將存活對象復制到另一個區域。
  2. 清空原區域的所有內存,完成垃圾回收。

缺點

  • 內存利用率低:需要預留一半內存空間,實際可用內存僅為總空間的 50%。
  • 當存活對象較多時,復制成本高。

標記---清除算法

主要分兩個階段進行:

  1. 標記階段:從根對象(如棧變量、靜態變量)出發,遍歷所有可達對象,并標記為 “存活”。
  2. 清除階段:掃描整個堆內存,將未被標記的對象(即垃圾)回收,并釋放其占用的內存空間。

缺點

  • 內存碎片化:回收后會產生大量不連續的內存碎片,可能導致后續無法分配大對象。
  • 效率較低:需要遍歷兩次內存(標記和清除)。

標記---整理算法

主要分兩個階段進行:

  1. 標記階段:同標記 - 清除算法,標記所有存活對象。
  2. 整理階段:將所有存活對象向內存一端移動,然后直接清理邊界外的所有內存(即垃圾對象占用的空間)。

缺點

  • 性能開銷大:需要移動對象,涉及內存復制,成本較高。

總結:由于不同算法的邏輯有所不同,所以他們的用處也有所不同。由于在新生代中的對象總是朝生夕滅,所以通常我們會使用復制算法進行垃圾回收;而老年代中的對象可以長期存活,所以我們通常適用標記---整理和標記清除算法。

?

垃圾收集器

Serial收集器(新生代)

? ? ? ?該收集器主要對新生代的垃圾進行收集清理,采用" 復制?"算法進行實現。

Serial Old收集器(老年代)

????????該收集器主要對老年代的垃圾進行收集清理,采用" 標記---整理?"算法進行實現。

? ? ? ? 他們兩個是串行收集器,也可以理解為單線程收集器,但在進行GC時會發生STW所以現在一般不使用。


Parallel Scavenge收集器(新生代)

? ? ? ? 該收集器主要對新生代的垃圾進行收集清理,采用" 復制?"算法進行實現。

Parallel Old收集器(老年代)

????????該收集器主要對老年代的垃圾進行收集清理,采用" 標記---整理?"算法進行實現。

????????他們兩個是多線程收集器,但在進行GC時會發生STW,但相對于前面性能會好很多。但是該收集器主要強調系統的吞吐量,所以會很容易出現系統上線后,內存占用過高的情況。


CMS收集器(老年代)

? ? ? ? 該收集器是一個基于" 標記---清除 "算法實現,是一種獲取最短回收停頓(STW)為目標的收集器,它可以實現讓收集線程和用戶線程并發。

????????CMS 的執行過程分為四個主要階段:

  1. 初始標記(Initial Mark, STW):通過 GC Roots 標記直接關聯到根對象的存活對象。

  2. 并發標記(Concurrent Mark):與應用線程并發執行,遍歷所有可達對象并標記存活對象。

  3. 重新標記(Remark, STW):修正并發標記期間因應用線程修改引用導致的標記錯誤。

  4. 并發清除(Concurrent Sweep)特點:無需暫停,但可能產生 “浮動垃圾”(即在清除階段新產生的垃圾,需等到下一次 GC 處理)。

? ? ? ? 由于該?標記---清除 算法所以會產生大量的內存空間碎片導致,空間的浪費;而且在并發清除的時候可能會產生浮動垃圾


G1收集器(老年代)

? ? ? ? 該搜集器主要針對大內存的機器,它采用局部性的收集思想將一塊大內存劃分為若干大小相同的獨立區域(Region),再講這些獨立的區域收集成一個回收集合,再進行處理。

G1 的垃圾回收周期主要分為以下階段:

  1. 初始標記(Initial Mark, STW):通過 GC Roots 標記直接關聯到根對象的存活對象。

  2. 并發標記(Concurrent Marking):與應用線程并發執行,遍歷所有可達對象并標記存活對象。

  3. 最終標記(Final Mark, STW):處理并發標記期間的引用變化(即未被標記的新對象),完成標記過程。

  4. 篩選回收(Cleanup and Evacuation, STW):根據 Region 的回收價值(垃圾占比)排序,選擇部分 Region 進行回收。

?

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

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

相關文章

二叉樹算法之【二叉樹的層序遍歷】

目錄 LeetCode-102題 LeetCode-102題 給定二叉樹的根節點root&#xff0c;返回其節點值的層序遍歷&#xff08;即逐層地&#xff0c;從左到右訪問所有節點&#xff09;。 class Solution {public List<List<Integer>> levelOrder(TreeNode root) {// checkif (r…

uniapp+vue3——通知欄標題縱向滾動切換

介紹 取巧&#xff0c;使用縱向輪播實現 <!-- 通知欄 --> <view class"noticeBox" v-if"notice.length>0"><image src"/static/images/index/noticeIcon.png" mode"aspectFill"></image><swiper class&…

BilldDesk 開源、免費、吊打收費軟件!白嫖黨最愛!遠程控制神器,沒有任何連接次數和畫質限制,同時顯示多屏、屏幕墻等高級功能

遠程控制軟件哪個好用&#xff1f;TeamViewer收費太貴&#xff0c;向日葵限制太多&#xff0c;QQ遠程又不穩定……別擔心&#xff01;今天給大家推薦一款完全免費、開源的遠程控制神器——BilldDesk&#xff01;它不僅功能強大&#xff0c;而且支持Windows、macOS、Linux、Andr…

ios UIAppearance 協議

一、前言 iOS 上提供了一個比較強大的工具UIAppearance&#xff0c;我們通過UIAppearance設置一些UI的全局效果&#xff0c;這樣就可以很方便的實現UI的自定義效果又能最簡單的實現統一界面風格。 (id)appearance ; 這個是這個協議里最重要的方法了 . 這個方法是統一全部改&am…

進階數據結構:用紅黑樹實現封裝map和set

? 嘿,各位技術潮人!好久不見甚是想念。生活就像一場奇妙冒險,而編程就是那把超酷的萬能鑰匙。此刻,陽光灑在鍵盤上,靈感在指尖跳躍,讓我們拋開一切束縛,給平淡日子加點料,注入滿滿的 passion。準備好和我一起沖進代碼的奇幻宇宙了嗎?Let’s go! 我的博客:yuanManGa…

【數據結構初階】--二叉樹(五)

&#x1f525;個人主頁&#xff1a;草莓熊Lotso &#x1f3ac;作者簡介&#xff1a;C研發方向學習者 &#x1f4d6;個人專欄&#xff1a; 《C語言》 《數據結構與算法》《C語言刷題集》《Leetcode刷題指南》 ??人生格言&#xff1a;生活是默默的堅持&#xff0c;毅力是永久的…

redis布隆過濾器解決緩存擊穿問題

在電商系統中&#xff0c;商品詳情頁是一個典型的高頻訪問場景。當用戶請求某個商品的詳情時&#xff0c;系統會優先從緩存中獲取數據。如果緩存中沒有該商品的詳情&#xff0c;系統會去數據庫查詢并更新緩存。然而&#xff0c;如果某個熱門商品的緩存失效&#xff0c;大量請求…

1+1>2!特征融合如何讓目標檢測更懂 “場景”?

來gongzhonghao【圖靈學術計算機論文輔導】&#xff0c;快速拿捏更多計算機SCI/CCF發文資訊&#xff5e;在多模態大模型&#xff08;MLLM&#xff09;時代&#xff0c;特征融合與目標檢測的研究方向正變得愈發關鍵。從紅外與可見光圖像的融合&#xff0c;到語音活動檢測中的特征…

詳解賽靈思SRIO IP并提供一種FIFO封裝SRIO的收發控制器仿真驗證

概述RapidIO標準定義為三層&#xff1a;邏輯層、傳輸層、物理層。邏輯層&#xff1a;定義總體協議和包格式&#xff0c;包含設備發起/完成事務的必要信息。傳輸層&#xff1a;提供包傳輸的路由信息&#xff08;對頂層不可見&#xff09;。物理層&#xff1a;描述設備級接口細節…

深度學習:簡介與任務分類總覽

一、什么是深度學習&#xff1f;1.1 深度學習的定義深度學習&#xff08;Deep Learning&#xff09;是機器學習的一種特殊形式&#xff0c;它依賴于具有多層結構的神經網絡自動從數據中學習特征并完成任務&#xff0c;如圖像識別&#xff0c;語音識別&#xff0c;自然語言處理等…

MSPM0開發學習筆記:二維云臺畫圖(2025電賽 附源代碼及引腳配置)

前言 今年的電賽&#xff08;2025&#xff09;&#xff0c;很多題都與云臺相關&#xff0c;因此為備戰電賽&#xff0c;博主這邊也是準備了一個由兩個42步進電機驅動的云臺并提前進行調試&#xff0c;避免賽題出來之后手忙腳亂的&#xff0c;這邊的兩個42步進電機采用同一個驅…

借助 Wisdom SSH 的 AI 助手構建 Linux 開發環境

借助Wisdom SSH的AI助手構建Linux開發環境 在Linux系統的開發場景中&#xff0c;快速、準確地搭建開發環境至關重要。Wisdom SSH憑借其強大的AI助手&#xff0c;能極大簡化這一過程&#xff0c;其官網為ssh.wisdomheart.cn。以下以在Ubuntu 22.04服務器上構建Python開發環境&am…

Python 程序設計講義(44):組合數據類型——集合類型:創建集合

Python 程序設計講義&#xff08;44&#xff09;&#xff1a;組合數據類型——集合類型&#xff1a;創建集合 目錄Python 程序設計講義&#xff08;44&#xff09;&#xff1a;組合數據類型——集合類型&#xff1a;創建集合一、集合的特征二、創建集合&#xff1a;使用set()函…

10 - 大語言模型 —Transformer 搭骨架,BERT 裝 “雙筒鏡”|解密雙向理解的核心

目錄 1、為什么 BERT 能 “懂” 語言&#xff1f;先看它的 “出身” 2、核心邏輯 2.1、“自學階段”—— 預訓練&#xff0c;像嬰兒學說話一樣積累語感 2.1.1、簡述 2.1.2、核心本事&#xff1a;“雙向注意力”&#xff0c;像人一樣 “聚焦重點” 2.2、“專項復習”—— …

【Spring Boot 快速入門】四、MyBatis

目錄MyBatis&#xff08;一&#xff09;入門簡介MyBatis 入門LombokMyBatis 基礎操作數據準備刪除預編譯新增更新查詢XML 映射文件MyBatis&#xff08;一&#xff09;入門 簡介 MyBatis 是一款 優秀的持久層框架&#xff0c;它支持 自定義 SQL、存儲過程以及高級映射&#xf…

Spring IOC 基于Cglib實現含構造函數的類實例化策略

作者&#xff1a;小凱 分享、讓自己和他人都能有所收獲&#xff01; 一、前言 技術成長&#xff0c;是對場景設計細節不斷的雕刻&#xff01; 你覺得自己的技術什么時候得到了快速的提高&#xff0c;是CRUD寫的多了以后嗎&#xff1f;想都不要想&#xff0c;絕對不可能&#xf…

composer 常用命令

### 設置鏡像源全局設置composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/當個項目設置composer config repo.packagist composer https://mirrors.aliyun.com/composer/恢復官方源composer config -g --unset repos.packagist### 常用源阿里云…

【python】Python爬蟲入門教程:使用requests庫

Python爬蟲入門教程&#xff1a;使用requests庫 爬蟲是數據獲取的重要手段&#xff0c;下面我將通過一個完整的示例&#xff0c;教你如何使用Python的requests庫編寫一個簡單的爬蟲。我們將以爬取豆瓣電影Top250為例。 【python】網絡爬蟲教程 - 教你用python爬取豆瓣電影 Top…

OpenCV圖像縮放:resize

圖像縮放是圖像處理中的基礎操作之一。無論是圖像預處理、數據增強還是圖像金字塔構建&#xff0c;cv::resize 都是我們最常用的函數之一。但你是否注意到&#xff0c;在 OpenCV 中同時還存在一個名為 cv::Mat::resize 的方法&#xff1f;這兩個函數雖然名字類似&#xff0c;但…

汽車、航空航天、適用工業虛擬裝配解決方案

一、現狀在制造業數字化轉型浪潮中&#xff0c;傳統裝配過程仍面臨諸多挑戰&#xff1a;物理樣機試錯成本高、裝配周期冗長、工藝優化依賴經驗、跨部門協作效率低下……如何打破“試錯-返工”的惡性循環&#xff1f;目前總裝工藝通過DELMIA、NX、Creo等工程軟件進行工藝裝配驗證…