【JVM】內存分配與回收原則

????????在 Java 開發中,自動內存管理是 JVM 的核心能力之一,而內存分配與回收的策略直接影響程序的性能和穩定性。本文將詳細解析 JVM 的內存分配機制、對象回收規則以及背后的設計思想,幫助開發者更好地理解 JVM 的 "自動化" 內存管理邏輯。

一、內存分配的核心原則

????????JVM 的內存分配遵循 "分代思想",即根據對象的存活周期將堆內存劃分為新生代和老年代,并針對不同區域采用不同的分配策略。

1. 對象優先在 Eden 區分配

????????大多數情況下,新創建的對象會首先被分配到新生代的 Eden 區。當 Eden 區沒有足夠空間時,JVM 會觸發一次 Minor GC(新生代垃圾回收)。

public class GCTest {public static void main(String[] args) {// 分配30MB對象(大于Eden區默認大小)byte[] allocation1 = new byte[30900*1024];}
}

????????通過-XX:+PrintGCDetails參數運行后可以觀察到:當 Eden 區無法容納大對象時,會觸發 Minor GC,若 Survivor 區仍無法容納,則會通過分配擔保機制將對象直接晉升到老年代。

2. 大對象直接進入老年代

????????大對象(需要大量連續內存的對象,如長字符串、數組)會被直接分配到老年代,這是為了避免大對象在新生代頻繁復制導致的性能損耗。

????????不同垃圾回收器對 "大對象" 的判定標準不同:

  • G1 收集器:根據-XX:G1HeapRegionSize設置的區域大小和-XX:G1MixedGCLiveThresholdPercent閾值判定
  • Parallel Scavenge 收集器:由虛擬機根據堆內存情況動態決定,無固定閾值

3. 長期存活的對象進入老年代

????????JVM 為每個對象維護一個 "年齡計數器",用于判斷對象是否應晉升到老年代:

  • 對象在 Eden 區出生,經過第一次 Minor GC 后存活并被移至 Survivor 區,年齡設為 1
  • 每在 Survivor 區熬過一次 Minor GC,年齡增加 1 歲
  • 當年齡達到閾值(默認 15 歲,可通過-XX:MaxTenuringThreshold設置)時,晉升到老年代

動態年齡調整
虛擬機并非嚴格按固定年齡閾值晉升對象。當 Survivor 區中相同年齡的對象總大小超過 Survivor 空間的 50%(可通過-XX:TargetSurvivorRatio調整)時,所有年齡大于或等于該年齡的對象會直接晉升到老年代。

注意不同收集器的默認閾值不同,CMS 收集器默認閾值為 6,Parallel 收集器默認 15。

二、內存回收的觸發機制

????????JVM 的垃圾回收(GC)按回收范圍可分為 Partial GC(部分回收)和 Full GC(整堆回收),其中 Partial GC 又可細分為:

  • Young GC:僅回收新生代
  • Old GC:僅回收老年代(僅 CMS 支持)
  • Mixed GC:回收新生代 + 部分老年代(僅 G1 支持)

1. Young GC 觸發條件

????????當新生代的 Eden 區分配滿時,觸發 Young GC。此時會有部分存活對象晉升到老年代,因此 Young GC 后老年代占用量可能上升。

2. Full GC 觸發條件

????????Full GC 會回收整個堆空間,觸發成本較高,常見觸發場景包括:

  • 老年代空間不足
  • 方法區(元空間)內存不足
  • 調用System.gc()(建議避免)
  • 空間分配擔保失敗

3. 空間分配擔保機制

????????為確保 Minor GC 的安全性,JVM 會在 Minor GC 前進行空間分配擔保檢查:

  • JDK 6 Update 24 前:檢查老年代最大可用連續空間是否大于新生代對象總大小或歷次晉升平均大小,否則觸發 Full GC
  • JDK 6 Update 24 后:只要老年代連續空間大于新生代總大小歷次晉升平均大小,就進行 Minor GC,否則觸發 Full GC

三、對象存活的判斷方法

????????垃圾回收的前提是準確判斷對象是否存活,JVM 主要采用兩種判斷算法:

1. 引用計數法

  • 原理:為每個對象設置引用計數器,引用增加時 + 1,引用失效時 - 1,計數器為 0 則標記為可回收
  • 缺陷:無法解決對象循環引用問題,因此主流 JVM 未采用

2. 可達性分析算法

  • 原理:以 "GC Roots" 為起點,遍歷引用鏈,不可達的對象被標記為可回收
  • GC Roots 包括
    • 虛擬機棧中引用的對象
    • 本地方法棧中引用的對象
    • 方法區中類靜態屬性引用的對象
    • 方法區中常量引用的對象
    • 同步鎖持有的對象

對象死亡的兩次標記

  1. 第一次標記:可達性分析后不可達的對象
  2. 第二次標記:檢查對象是否需要執行finalize()方法,若無需執行或已執行,則判定為死亡

注意:finalize()方法已被 JDK 9 標記為過時,建議避免使用。

四、引用類型與回收策略

????????JDK 1.2 后將引用分為四類,強度依次減弱,影響對象的回收時機:

引用類型特點應用場景
強引用Object obj = new Object()普通對象引用,內存不足時不會回收一般對象引用
軟引用SoftReference內存不足時會被回收內存敏感的緩存
弱引用WeakReference無論內存是否充足,GC 時都會回收臨時緩存
虛引用PhantomReference不影響對象生命周期,僅用于跟蹤回收管理直接內存

軟引用和弱引用可配合ReferenceQueue使用,當引用對象被回收時,引用實例會被加入隊列,便于后續處理。

五、實戰建議與最佳實踐

  1. 避免創建大對象:大對象直接進入老年代,可能頻繁觸發 Full GC
  2. 合理設置新生代大小:新生代過小會導致 Young GC 頻繁,過大則會延長 GC 時間
  3. 選擇合適的垃圾收集器
    • 追求吞吐量:選擇 Parallel Scavenge + Parallel Old
    • 追求低延遲:選擇 G1 或 ZGC
  4. 監控 GC 性能:通過-XX:+PrintGCDetails-XX:+PrintGCLogs等參數分析 GC 日志
  5. 慎用System.gc():該方法僅為建議,可能觸發 Full GC 影響性能

六、總結

????????JVM 的內存分配與回收機制是自動內存管理的核心,其設計遵循 "分代收集" 思想,通過不同區域的針對性策略實現高效的內存管理。理解這些原則有助于開發者寫出更優的代碼,避免常見的內存問題(如 OOM),并在必要時進行有效的性能調優。

????????掌握內存分配規律、GC 觸發機制和引用類型特性,是深入理解 JVM 的重要一步,也是應對高并發、高性能場景的必備知識。

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

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

相關文章

Qt獲取hid設備信息

Qt 中通過 HID&#xff08;Human Interface Device&#xff09;接口獲取指定的 USB 設備&#xff0c;并讀取其數據。資源文件中包含了 hidapi.h、hidapi.dll 和 hidapi.lib。通過這些文件&#xff0c;您可以在 Qt 項目中實現對 USB 設備的 HID 接口調用。#include <QObject&…

Anaconda Jupyter 使用注意事項

Anaconda Jupyter 使用注意事項 1.將cell轉換為markdown。 First, select the cell you want to convertPress Esc to enter command mode (the cell border should turn blue)Press M to convert the cell to Markdown在編輯模式下按下ESC鍵&#xff0c;使單元塊&#xff08;c…

[硬件電路-20]:模擬信號處理運算與數字信號處理運算的相同點與不同點

模擬信號處理運算與數字信號處理運算是信號處理領域的兩大核心方法&#xff0c;二者在信號形式、處理機制、性能特點和應用場景上存在顯著差異&#xff0c;但也共享一些基礎目標與理論支撐。以下從多個維度進行系統對比分析&#xff1a;一、相同點1. 核心目標一致信號變換與分析…

Redis 高頻面試題

1. 緩存穿透 1.1 描述 用戶想要查詢某個數據,在 Redis 中查詢不到,即沒有緩存命中,這時就會直接訪問數據庫進行查詢。當請求量超出數據庫最大承載量時,就會導致數據庫崩潰。這種情況一般發生在非正常 URL 訪問,目的不是為了獲取數據,而是進行惡意攻擊。 1.2 現象 1、應…

OWASP Top 10 攻擊場景實戰

OWASP (開放式Web應用程序安全項目) Top 10 榜單是全球公認的、針對Web應用最關鍵安全風險的權威指南。它不是一份詳盡無遺的清單&#xff0c;而是一份凝聚了安全專家共識的“高危預警”。本文將不止于羅列這些風險&#xff0c;而是深入每個風險的核心&#xff0c;通過生動的比…

Three.js 實戰:使用 PBR 貼圖打造真實地面材質

在 Three.js 中&#xff0c;我們可以通過 MeshStandardMaterial 材質配合多張貼圖來實現真實的地面效果。這種方式模擬了物理世界中光照與表面材質的復雜交互&#xff0c;常用于構建高質量場景&#xff0c;如數字孿生、建筑可視化、游戲等。 本文將以一個完整示例為基礎&#x…

Java基礎的總結問題(第一篇)

JDK和JRE的區別&#xff1f;JRE是Java運行環境&#xff08;Java Runtime Environment&#xff09;&#xff0c;包含了JVM和Java核心類庫JDK是Java開發工具包&#xff08;Java Developers Kit&#xff09;,包含了JRE和Java常見的開發工具與equals的區別&#xff1f;可以用來比較…

[智能算法]MOEA/D算法的Python實現

一、初始化不同于NSGA-II&#xff0c;MOEA/D在進行迭代之前需要先進行初始化&#xff0c;初始化的主要內容是計算個體向量權重之間的歐氏距離&#xff0c;并得出其鄰域集合。# 計算T個鄰居 def cpt_W_Bi_T(moead):# 設置的鄰居個數錯誤(自己不能是自己的鄰居)if moead.T_size &…

Java設計模式之-組合模式

什么是組合模式&#xff1f; 組合模式允許你將對象組合成樹形結構來表示"部分-整體"的層次結構。它讓客戶端能夠以統一的方式處理單個對象和對象組合。 簡單來說&#xff0c;就像公司的組織結構&#xff1a; 公司有部門部門有小組小組有員工但無論是對公司、部門還是…

2021-10-29 C++與反轉數的和

緣由輸入一個三位數 與它倒過來的數相加&#xff0c;輸出和-編程語言-CSDN問答 直接寫 int n0,nn0,nnn0; cin>>n;nnn; while(nn)nnn*10,nnnnn%10,nn/10; cout<<nnnn<<endl; 緣由https://ask.csdn.net/questions/7552128 int 反轉數(int n) { int nn 0…

論安全架構設計(威脅與措施)

安全架構威脅與措施摘要2021年4月&#xff0c;我有幸參與了某保險公司的“優車險”項目的建設開發工作&#xff0c;該系統以車險報價、車險投保和報案理賠為核心功能&#xff0c;同時實現了年檢代辦、道路救援、一鍵挪車等增值服務功能。在本項目中&#xff0c;我被安排擔任架構…

022_提示緩存與性能優化

提示緩存與性能優化 目錄 緩存技術概述緩存工作原理實現方法詳解成本優化策略性能優化實踐高級應用場景最佳實踐指南 緩存技術概述 什么是提示緩存 提示緩存是Claude API的一項優化功能&#xff0c;允許緩存提示的特定部分以便重復使用&#xff0c;從而顯著減少處理時間和…

【AI交叉】地理:人工智能如何推動地理科學的智能轉型?

隨著人工智能&#xff08;AI&#xff09;技術的快速發展&#xff0c;越來越多的傳統學科開始與之融合&#xff0c;催生出一系列跨學科的新研究方向和應用場景。地理科學作為研究地球表層自然與人文現象的綜合性學科&#xff0c;也在這一浪潮中迎來轉型契機。 AI與地理學的交叉正…

iOS高級開發工程師面試——關于網絡

iOS高級開發工程師面試——關于網絡 一、談談對 HTTP、HTTPS 的理解1. HTTP協議:2. HTTPS 協議二、TCP、UDP 和 SocketTCPUDPTCP 和 UDP 的區別?Socket一、談談對 HTTP、HTTPS 的理解 1. HTTP協議: 超文本傳輸協議,他是基于TCP應用層協議。 是無連接 無狀態 的,需要通過…

跟著Nature正刊學作圖:回歸曲線+散點圖

&#x1f4cb;文章目錄復現目標圖片繪圖前期準備繪制左側回歸線圖繪制右側散點圖組合拼圖 (關鍵步驟&#xff01;)跟著「Nature」正刊學作圖&#xff0c;今天挑戰復現Nature文章中的一張組合圖–左邊為 回歸曲線、右邊為 散點圖。這種組合圖在展示相關性和分組效應時非常清晰有…

LVS集群調度器

目錄 集群和分布式 LVS運行原理 LVS概念 LVS的集群類型 實驗配置 安裝LVS ipvsadm命令參數 1.管理集群服務中的增刪改 2.管理集群服務中的RS增刪改 3.lvs調度策略的備份與恢復 4.lvs調度策略的開機啟動 LVS-NAT模式 LVS-DR模式 集群和分布式 集群&#xff08;Clu…

【React Natve】NetworkError 和 TouchableOpacity 組件

NetworkError公共組件 import SimpleLineIcons from "expo/vector-icons/SimpleLineIcons"; import { StyleSheet, Text, View } from "react-native";export default function NetworkError() {return (<View style{styles.container}><SimpleL…

Linux 驅動中 Timer / Tasklet / Workqueue 的作用與對比

Linux 驅動中 Timer / Tasklet / Workqueue 的作用與對比 &#x1f9e9; 1. 使用場景概覽&#xff08;對比表&#xff09;機制執行上下文是否可睡眠使用場景常用接口Timer中斷上下文? 不可睡眠延遲執行&#xff08;如防抖、超時處理&#xff09;add_timer() 等Tasklet軟中斷上…

JavaScript中關于proxy的作用以及和Object.defineProperty的區別

之前寫了一篇介紹 Object.defineProperty的&#xff0c;提到proxy&#xff0c;二者有一些共性&#xff0c;也都是前端框架Vue的核心機制&#xff0c;所以再寫一篇介紹一下proxy的基礎原理和使用。 在 JavaScript 中&#xff0c;Proxy 是 ES6 引入的一個元編程特性&#xff0c;用…

HTTP性能優化實戰技術

HTTP性能優化實戰技術文章大綱 理解HTTP性能優化的核心指標 關鍵指標&#xff1a;延遲、吞吐量、TTFB&#xff08;Time To First Byte&#xff09;、頁面加載時間影響性能的因素&#xff1a;網絡延遲、服務器響應時間、資源大小、協議效率 減少HTTP請求數量 合并資源文件&#…