JVM 深度解析

一、JVM 概述
1.1 什么是 JVM?

JVM(Java Virtual Machine,Java 虛擬機)是 Java 程序運行的核心引擎。它像一個“翻譯官”,將 Java 字節碼轉換為機器能理解的指令,并管理程序運行時的內存、線程等資源。

核心功能

  • 跨平臺運行:一次編譯,到處運行(Write Once, Run Anywhere)
  • 內存管理:自動分配和回收內存(垃圾回收)
  • 安全控制:字節碼驗證、權限管理

類比說明

  • Java 程序?→ 一本用中文寫的菜譜
  • JVM?→ 一位精通各國語言的廚師
  • 不同操作系統?→ 不同國家的廚房
  • 字節碼?→ 國際通用的菜譜符號
二、JVM 核心架構

JVM 由三大核心模塊組成:

模塊功能關鍵技術
類加載系統加載.class文件到內存雙親委派機制
運行時數據區管理程序運行時的內存分配堆、棧、方法區
執行引擎解釋/編譯字節碼為機器指令解釋器、JIT編譯器、垃圾回收

三、類加載機制
3.1 類加載流程

類加載分為三個階段:

  1. 加載(Loading)
    • 查找.class文件
    • 將字節碼轉換為方法區的數據結構
  2. 鏈接(Linking)
    • 驗證:檢查字節碼是否符合規范
    • 準備:為靜態變量分配內存(默認初始值)
    • 解析:將符號引用轉為直接引用
  3. 初始化(Initialization)
    • 執行靜態代碼塊(<clinit>方法)
    • 為靜態變量賦真實值

示例

public class Demo {static int value = 10; // 準備階段 value=0,初始化階段 value=10static {System.out.println("靜態代碼塊執行");}
}
3.2 雙親委派模型

加載器層級

  1. Bootstrap ClassLoader:加載jre/lib核心庫(如java.lang.*)
  2. Extension ClassLoader:加載jre/lib/ext擴展庫
  3. Application ClassLoader:加載用戶類路徑(classpath)
  4. 自定義ClassLoader:用戶自定義加載邏輯

工作流程

  1. 子加載器收到加載請求后,先委派父加載器處理
  2. 父加載器無法完成時,子加載器才嘗試加載

優勢

  • 避免核心類被篡改(如自定義java.lang.String)
  • 保證類全局唯一性
  • public class ClassLoaderDemo {public static void main(String[] args) {// 查看不同類的加載器System.out.println(String.class.getClassLoader()); // null(Bootstrap加載器)System.out.println(ClassLoaderDemo.class.getClassLoader()); // AppClassLoader}
    }
    
    四、運行時數據區
    4.1 內存結構總覽
  • +-------------------+
    |   方法區(Method Area)   | ← 存儲類信息、常量、靜態變量
    +-------------------+
    |   堆(Heap)              | ← 所有對象實例和數組
    +-------------------+
    |   虛擬機棧(VM Stack)     | ← 線程私有的方法調用棧幀
    |   本地方法棧(Native Stack)| ← 調用本地(Native)方法
    |   程序計數器(PC Register) | ← 當前線程執行的字節碼行號
    +-------------------+
    
    4.2 堆(Heap)
  • 分代設計
    • 新生代(Young Generation):新創建的對象
      • Eden區(80%)
      • Survivor區(From + To,各10%)
    • 老年代(Old Generation):長期存活的對象
    • 元空間(Metaspace,JDK8+):類元數據(替代永久代)
  • 對象分配流程

  • 新對象優先分配到Eden區
  • Eden滿時觸發Minor GC
  • 存活對象復制到Survivor區(年齡+1)
  • 年齡達到閾值(默認15)后進入老年代

示例代碼

public class HeapDemo {public static void main(String[] args) {List<byte[]> list = new ArrayList<>();while (true) {list.add(new byte[1024 * 1024]); // 持續創建1MB數組,觸發OOM}}
}
// 輸出:java.lang.OutOfMemoryError: Java heap space
4.3 虛擬機棧(VM Stack)
  • 棧幀結構
    • 局部變量表(Local Variables)
    • 操作數棧(Operand Stack)
    • 動態鏈接(Dynamic Linking)
    • 方法返回地址(Return Address)
  • 棧溢出示例
  • public class StackOverflowDemo {static void recursiveCall() {recursiveCall(); // 無限遞歸}public static void main(String[] args) {recursiveCall();}
    }
    // 輸出:java.lang.StackOverflowError
    
    4.4 方法區(Method Area)
  • 存儲內容
    • 類結構信息(字段、方法、構造函數)
    • 運行時常量池
    • JIT編譯后的代碼緩存
  • 元空間溢出示例

  • public class MetaspaceOOM {static class OOMObject {}public static void main(String[] args) {// 使用CGLIB動態生成類Enhancer enhancer = new Enhancer();enhancer.setSuperclass(OOMObject.class);enhancer.setCallback((MethodInterceptor) (obj, method, args1, proxy) -> proxy.invokeSuper(obj, args1));while (true) {enhancer.create(); // 持續生成代理類}}
    }
    // 輸出:java.lang.OutOfMemoryError: Metaspace
    
    五、垃圾回收(GC)
    5.1 判斷對象可回收
  • 引用計數法:循環引用問題(已棄用)
  • 可達性分析:從GC Roots出發,不可達的對象可回收
    • GC Roots包括:
      • 虛擬機棧中引用的對象
      • 方法區中靜態屬性引用的對象
      • 本地方法棧中JNI引用的對象
  • 示例
  • public class GCRootsDemo {Object instance;public static void main(String[] args) {GCRootsDemo a = new GCRootsDemo();GCRootsDemo b = new GCRootsDemo();a.instance = b;b.instance = a;a = null;b = null; // 此時兩個對象仍互相引用,但不可達,會被回收System.gc();}
    }
    
    5.2 垃圾回收算法
    算法原理適用場景
    標記-清除標記可回收對象后清除老年代(CMS)
    復制將存活對象復制到新空間新生代(Serial、ParNew)
    標記-整理標記后整理內存空間老年代(Serial Old)
    分代收集根據對象年齡采用不同算法現代JVM默認方案

復制算法示意圖

新生代內存布局:
+-----------+------------+-----------+
|   Eden    | From(S0)   | To(S1)    |
+-----------+------------+-----------+
Minor GC后存活對象復制到To區,清空Eden和From
5.3 垃圾收集器
收集器特點適用場景
Serial單線程,Stop-The-World客戶端模式
ParNewSerial的多線程版本新生代(配合CMS)
CMS并發標記清除,低停頓老年代
G1分區收集,可預測停頓時間JDK9+默認
ZGC低延遲(<10ms),大堆內存超大內存應用

G1收集器示例配置

java -XX:+UseG1GC -Xmx4g -XX:MaxGCPauseMillis=200 MyApp
六、執行引擎
6.1 解釋執行
  • 逐行解釋字節碼:效率低,但啟動快
  • 示例javap -c MyClass.class?查看字節碼
6.2 JIT編譯(Just-In-Time)
  • 熱點代碼檢測:統計方法調用次數
  • 編譯優化技術
    • 方法內聯(Method Inlining)
    • 逃逸分析(Escape Analysis)
    • 循環展開(Loop Unrolling)

逃逸分析示例

public class EscapeAnalysisDemo {public static void main(String[] args) {for (int i = 0; i < 1000000; i++) {createObject();}}static void createObject() {Object obj = new Object(); // 對象未逃逸,可能被棧上分配}
}
6.3 分層編譯(Tiered Compilation)
  • 編譯級別
    • 0:解釋執行
    • 1:簡單快速編譯(C1)
    • 2:完全優化編譯(C2)
  • 參數控制-XX:TieredStopAtLevel=3

七、性能監控與調優
7.1 常用工具
工具功能示例命令
jps查看Java進程IDjps -l
jstat監控GC情況jstat -gcutil <pid> 1000
jmap生成堆轉儲快照jmap -dump:format=b,file=heap.bin <pid>
VisualVM圖形化性能分析監控CPU、內存、線程

jstat輸出示例

S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
0.00 100.00  25.43  68.50  95.12  91.03     10    0.123     2    0.456    0.579
7.2 常見JVM參數
參數作用示例值
-Xms?/?-Xmx初始/最大堆內存-Xms512m -Xmx4g
-XX:NewRatio新生代與老年代比例-XX:NewRatio=3(新生代占1/4)
-XX:SurvivorRatioEden與Surviv區比例-XX:SurvivorRatio=8(Eden:S0:S1=8:1:1)
-XX:+PrintGCDetails打印詳細GC日志

八、實戰案例
8.1 內存泄漏排查

步驟

  1. 使用jps獲取進程ID
  2. jmap -dump:format=b,file=heap.bin <pid>?導出堆快照
  3. 用MAT(Memory Analyzer Tool)分析
  4. 查找支配樹中的大對象

常見原因

  • 靜態集合類持有對象引用
  • 未關閉的數據庫連接
  • 監聽器未注銷
8.2 GC優化案例

問題現象:Full GC頻繁,每次耗時2秒
分析步驟

  1. jstat -gcutil <pid> 1000?發現老年代快速填滿
  2. jmap -histo <pid>?發現大量相同類實例
  3. 檢查代碼發現緩存未設置上限
    解決方案:改用LRU緩存,限制最大條目數

九、JVM發展前沿
9.1 GraalVM
  • 多語言支持:Java、JavaScript、Python等
  • 原生鏡像(Native Image):提前編譯為本地可執行文件
  • 示例native-image -jar myapp.jar
9.2 Project Loom
  • 虛擬線程(Virtual Threads):輕量級線程,支持百萬級并發
  • 示例
  • Thread.startVirtualThread(() -> {System.out.println("Hello from virtual thread!");
    });
    
    9.3 ZGC與Shenandoah
  • 亞毫秒級停頓:適用于金融交易系統
  • 配置示例
  • java -XX:+UseZGC -Xmx16g -XX:+UseLargePages MyApp
    

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

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

相關文章

OpenCV CUDA 模塊圖像過濾-----創建一個計算圖像導數的濾波器函數createDerivFilter()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::cuda::createDerivFilter 是 OpenCV CUDA 模塊中的一個工廠函數&#xff0c;用于創建一個計算圖像導數的濾波器。這個濾波器可以用來計算圖像…

Spring Boot 接口開發實戰指南

Spring Boot 接口開發實戰指南 一、基礎接口開發步驟 1.1 添加必要依賴 <!-- pom.xml --> <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></depen…

題目 3325: 藍橋杯2025年第十六屆省賽真題-2025 圖形

題目 3325: 藍橋杯2025年第十六屆省賽真題-2025 圖形 時間限制: 2s 內存限制: 192MB 提交: 494 解決: 206 題目描述 小藍要畫一個 2025 圖形。圖形的形狀為一個 h w 的矩形&#xff0c;其中 h 表示圖形的高&#xff0c;w 表示圖形的寬。當 h 5,w 10 時&#xff0c;圖形如下所…

UML 時序圖 使用案例

UML 時序圖 UML 時序圖 (Sequence Diagram)時序圖的主要元素消息類型詳解時序圖示例時序圖繪制步驟時序圖的應用場景 UML 時序圖 (Sequence Diagram) 時序圖是UML(統一建模語言)中用于展示對象之間交互行為的動態視圖&#xff0c;它特別強調消息的時間順序。 時序圖的主要元素…

PPT連同備注頁(演講者模式)一塊轉為PDF

首先&#xff0c;進入創建PDF/XPS&#xff1a; 然后進入選項&#xff1a; 發布選項-發布內容里選備注頁&#xff1a; 導出的原始結果是這樣的&#xff1a; 這個時候裁剪一下&#xff0c;范圍為所有頁面&#xff1a; 最終結果&#xff1a; 如果導出不選“備注頁”而是只勾選“包…

AI時代新詞-多模態(Multimodal)

一、什么是多模態&#xff08;Multimodal&#xff09;&#xff1f; 多模態&#xff08;Multimodal&#xff09;是指在人工智能中&#xff0c;融合多種不同類型的信息&#xff08;如文本、圖像、語音、視頻等&#xff09;進行處理和分析的技術。與傳統的單一模態&#xff08;例…

【圖像大模型】Stable Diffusion XL:下一代文本到圖像生成模型的技術突破與實踐指南

Stable Diffusion XL&#xff1a;下一代文本到圖像生成模型的技術突破與實踐指南 一、架構設計與技術演進1.1 核心架構革新1.2 關鍵技術突破1.2.1 雙文本編碼器融合1.2.2 動態擴散調度 二、系統架構解析2.1 完整生成流程2.2 性能指標對比 三、實戰部署指南3.1 環境配置3.2 基礎…

圖像分割技術的實現與比較分析

引言 圖像分割是計算機視覺領域中的一項基礎技術&#xff0c;其目標是將數字圖像劃分為多個圖像子區域&#xff08;像素的集合&#xff09;&#xff0c;以簡化圖像表示&#xff0c;便于后續分析和理解。在醫學影像、遙感圖像分析、自動駕駛、工業檢測等眾多領域&#xff0c;圖…

摩爾線程S4000國產信創計算卡性能實戰——Pytorch轉譯,多卡P2P通信與MUSA編程

簡介 MTT S4000 是基于摩爾線程曲院 GPU 架構打造的全功能元計算卡&#xff0c;為千億規模大語言模型的訓練、微調和推理進行了定制優化&#xff0c;結合先進的圖形渲染能力、視頻編解碼能力和超高清 8K HDR 顯示能力&#xff0c;助力人工智能、圖形渲染、多媒體、科學計算與物…

「從0到1」構建工業物聯網監控系統:ARM+Quarkus+Prometheus技術棧全記錄

在工業4.0浪潮中&#xff0c;邊緣計算正成為智能制造的核心基礎設施。ARM架構邊緣計算機憑借其低功耗、高能效比和模塊化設計優勢&#xff0c;正在重塑工業物聯網&#xff08;IIoT&#xff09;的監控體系。當Java的跨平臺能力與Prometheus的實時監控體系相結合&#xff0c;為工…

【HW系列】—web常規漏洞(文件上傳漏洞)

文章目錄 一、簡介二、危害三、文件檢測方式分類四、判斷文件檢測方式五、文件上傳繞過技術六、漏洞防御措施 一、簡介 文件上傳漏洞是指Web應用程序在處理用戶上傳文件時&#xff0c;未對文件類型、內容、路徑等進行嚴格校驗和限制&#xff0c;導致攻擊者可上傳惡意文件&…

如何設計ES的冷熱數據分離架構?Elasticsearch 集群如何實現高可用?如何避免腦裂問題?如果出現腦裂如何恢復?

以下為Elasticsearch架構設計與高可用方案詳細說明&#xff1a; 冷熱架構 一、冷熱數據分離架構設計&#xff08;文字描述模擬架構圖&#xff09; [Hot Layer] │ ├─ SSD節點組&#xff08;3節點&#xff09; │ ├─ 角色&#xff1a;ingest/data/hot │ ├─ 存…

Trivy 鏡像漏洞掃描:從零入門到實戰指南

&#x1f525;「炎碼工坊」技術彈藥已裝填&#xff01; 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 ——手把手帶你掌握容器安全核心工具 一、安裝配置&#xff1a;三步完成 Trivy 部署 Trivy 是由 Aqua Security 開發的開源容器安全工具&#xff0c;支持…

SQL基礎概念以及SQL的執行方式

1. SQL入門 1.1. SQL語言功能 可以把 SQL 語言按照功能劃分成以下的 4 個部分&#xff1a; DDL&#xff0c;英文叫做 Data Definition Language&#xff0c;也就是數據定義語言&#xff0c;它用來定義我們的數據庫對象&#xff0c;包括數據庫、數據表和列。通過使用 DDL&…

Rust 1.0 發布十周年,夢想再度揚帆起航!

目錄 引言&#xff1a;發布十周年&#xff0c;鋒芒露今朝 一、Rust的誕生&#xff1a;源于安全的初心 二、Rust 1.0&#xff1a;十年耕耘&#xff0c;碩果累累 三、核心利器&#xff1a;安全、并發與性能的十年錘煉 四、生態與應用&#xff1a;十年拓展&#xff0c;遍地開…

x86 與 ARM 匯編深度對比:聚焦 x86 匯編的獨特魅力

一、引言 匯編語言是硬件與軟件的橋梁&#xff0c;x86 和 ARM 作為兩大主流架構&#xff0c;其匯編語言在設計理念、指令集、編程風格上差異顯著。本文以 x86 匯編為核心&#xff0c;結合與 ARM 的對比&#xff0c;解析 x86 匯編的技術細節與應用場景&#xff0c;助力開發者深…

入駐面包多了

前言 入駐面包多了&#xff0c;其實已經開通面包多賬號老久了&#xff0c;一直沒有認證&#xff0c;因為沒什么拿得出手的作品。 后邊會努力沉淀&#xff0c;希望能出一些作品&#xff0c;給大家帶來一些幫助&#xff0c;然后能賺到一些些奶茶錢。 一個小工具 上架了一個Win…

Python----目標檢測(MS COCO數據集)

一、MS COCO數據集 COCO 是一個大規模的對象檢測、分割和圖像描述數據集。COCO有幾個 特點&#xff1a; Object segmentation&#xff1a;目標級的分割&#xff08;實例分割&#xff09; Recognition in context&#xff1a;上下文中的識別&#xff08;圖像情景識別&#xff0…

【Spring AI集成實戰】基于NVIDIA LLM API構建智能聊天應用:從配置到函數調用全解析

【Spring AI集成實戰】基于NVIDIA LLM API構建智能聊天應用&#xff1a;從配置到函數調用全解析 前言 在人工智能應用開發領域&#xff0c;大語言模型&#xff08;LLM&#xff09;的集成能力至關重要。NVIDIA作為全球領先的GPU廠商&#xff0c;其LLM API提供了對Meta Llama-3.…

通用的管理賬號設置設計(一)

背景 首先說明一下需求背景&#xff1a; 在整個角色分類中分為管理員和用戶&#xff0c;用戶可以分為很多級別&#xff0c;比如用戶處于哪個組&#xff08;group&#xff09;&#xff0c;用戶處于哪個site&#xff08;城市&#xff09;。管理員可以&#xff1a; 2.1 鎖定整個…