最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA內(nèi)存區(qū)域示例詳解

 更新時間:2025年12月27日 09:39:45   作者:此時已鶯飛草長  
Java內(nèi)存區(qū)域包括程序計數(shù)器、虛擬機棧、本地方法棧、堆、元空間和直接內(nèi)存,分別用于線程私有數(shù)據(jù)和線程共享數(shù)據(jù),理解這些區(qū)域有助于定位內(nèi)存問題、優(yōu)化JVM性能和編寫高性能代碼,本文介紹java內(nèi)存區(qū)域的相關(guān)知識,感興趣的朋友一起看看吧

一、Java內(nèi)存區(qū)域的核心定義

Java內(nèi)存區(qū)域(也叫「JVM運行時數(shù)據(jù)區(qū)」)是 Java虛擬機(JVM)在運行Java程序時,對內(nèi)存的結(jié)構(gòu)化劃分 —— JVM將申請到的內(nèi)存拆分成多個功能明確、邊界清晰的區(qū)域,每個區(qū)域負責(zé)存儲特定類型的數(shù)據(jù),并有專屬的內(nèi)存分配、回收規(guī)則和生命周期。

核心目的:精細化管理內(nèi)存(避免內(nèi)存混亂、提升分配/回收效率),同時隔離不同類型數(shù)據(jù)的生命周期(比如線程私有數(shù)據(jù)隨線程銷毀,共享數(shù)據(jù)統(tǒng)一回收)。

?? 關(guān)鍵澄清:
很多人會混淆「Java內(nèi)存區(qū)域」和之前講的「Java內(nèi)存模型(JMM)」,兩者完全不同:

維度Java內(nèi)存區(qū)域(JVM運行時數(shù)據(jù)區(qū))Java內(nèi)存模型(JMM)
本質(zhì)物理內(nèi)存的「功能劃分」(存儲結(jié)構(gòu))抽象規(guī)范(解決多線程內(nèi)存一致性問題)
關(guān)注對象內(nèi)存“存什么、在哪存、何時回收”多線程“如何安全訪問共享變量”
核心目標內(nèi)存分配與回收保證并發(fā)的可見性、原子性、有序性

二、Java內(nèi)存區(qū)域的整體結(jié)構(gòu)(JDK 8+)

JVM規(guī)范將內(nèi)存區(qū)域分為「線程私有區(qū)域」和「線程共享區(qū)域」,JDK 8是重要分界點(移除永久代,改用元空間),以下基于JDK 8及以后版本講解:

Java內(nèi)存區(qū)域
├── 線程私有區(qū)域(每個線程獨立擁有,隨線程銷毀)
│   ├── 程序計數(shù)器
│   ├── 虛擬機棧(Java棧)
│   └── 本地方法棧
├── 線程共享區(qū)域(所有線程共用,隨JVM啟動/銷毀)
│   ├── 堆(Java Heap)
│   └── 元空間(Metaspace,替代JDK7的永久代)
└── 直接內(nèi)存(Direct Memory,非JVM規(guī)范定義,堆外內(nèi)存)

三、逐個解析:每個內(nèi)存區(qū)域的作用、內(nèi)容與問題

1. 程序計數(shù)器(Program Counter Register)

核心理解

可以看作「線程的執(zhí)行進度條」—— 記錄當(dāng)前線程正在執(zhí)行的Java字節(jié)碼指令的地址(或本地方法的執(zhí)行地址),線程切換后能通過計數(shù)器恢復(fù)執(zhí)行位置。

關(guān)鍵特性

  • 線程私有:每個線程有獨立的程序計數(shù)器,避免線程間干擾;
  • 無OOM:是JVM內(nèi)存區(qū)域中唯一不會拋出 OutOfMemoryError(OOM)的區(qū)域;
  • 存儲內(nèi)容
    • 執(zhí)行Java方法時:存儲當(dāng)前字節(jié)碼指令的行號(通過pc寄存器記錄);
    • 執(zhí)行Native方法(如C/C++實現(xiàn)的方法)時:計數(shù)器值為undefined(本地方法由操作系統(tǒng)調(diào)度,JVM不跟蹤)。

示例理解

比如線程A執(zhí)行到main方法的第10行代碼,程序計數(shù)器記錄“第10行對應(yīng)的字節(jié)碼地址”;此時CPU切換到線程B執(zhí)行,線程A暫停;當(dāng)CPU切回線程A時,通過計數(shù)器找到之前的地址,繼續(xù)從第10行執(zhí)行。

2. 虛擬機棧(Java Virtual Machine Stack)

核心理解

Java方法執(zhí)行提供內(nèi)存空間 —— 每個Java方法被調(diào)用時,JVM會為該方法創(chuàng)建一個「棧幀(Stack Frame)」,棧幀入棧;方法執(zhí)行完成后,棧幀出棧。虛擬機棧的生命周期與線程完全一致。

棧幀的核心內(nèi)容(方法的“內(nèi)存快照”)

每個棧幀包含4部分,是方法執(zhí)行的核心內(nèi)存載體:

棧幀組成作用
局部變量表存儲方法的局部變量(基本類型、對象引用、returnAddress類型),容量固定
操作數(shù)棧方法執(zhí)行時的臨時運算空間(比如執(zhí)行a+b時,先壓入a、b,再彈出計算)
動態(tài)鏈接指向運行時常量池的引用(比如方法調(diào)用時解析符號引用為直接引用)
方法出口記錄方法執(zhí)行完成后返回的位置(比如回到調(diào)用方的哪一行)

關(guān)鍵特性與問題

  • 線程私有:每個線程有獨立的虛擬機棧,互不干擾;
  • 大小限制:棧的容量可通過-Xss參數(shù)設(shè)置(如-Xss1M,默認約1M);
  • 常見異常
    • StackOverflowError:棧深度超出限制(比如無限遞歸調(diào)用方法,棧幀不斷入棧,撐滿棧);
    • OutOfMemoryError:虛擬機棧支持動態(tài)擴展時,擴展內(nèi)存不足(極少發(fā)生,主流JVM棧容量固定)。

代碼示例:觸發(fā)StackOverflowError

/**
 * 無限遞歸調(diào)用,虛擬機棧幀不斷入棧,觸發(fā)棧溢出
 */
public class StackOverflowDemo {
    private static int depth = 0;
    public static void recursive() {
        depth++;
        recursive(); // 無限遞歸,棧幀持續(xù)入棧
    }
    public static void main(String[] args) {
        try {
            recursive();
        } catch (StackOverflowError e) {
            System.out.println("遞歸深度:" + depth);
            System.out.println("異常:" + e);
        }
    }
}

執(zhí)行結(jié)果(示例):

遞歸深度:10886
異常:java.lang.StackOverflowError

解釋:每次調(diào)用recursive()都會創(chuàng)建新棧幀,直到虛擬機棧被撐滿,拋出棧溢出異常。

3. 本地方法棧(Native Method Stack)

核心理解

與虛擬機棧功能類似,但專為Native方法(非Java語言實現(xiàn)的方法,如C/C++方法)提供內(nèi)存支持。

關(guān)鍵特性

  • 線程私有:每個線程有獨立的本地方法棧;
  • 存儲內(nèi)容:Native方法的執(zhí)行狀態(tài)(如局部變量、寄存器狀態(tài)等);
  • 常見異常:和虛擬機棧一致,會拋出StackOverflowErrorOutOfMemoryError
  • 示例:Java中的Object.hashCode()System.arraycopy()等方法底層是Native實現(xiàn),執(zhí)行時會用到本地方法棧。

4. 堆(Java Heap)

核心理解

JVM中最大的內(nèi)存區(qū)域,唯一目的是存儲「對象實例和數(shù)組」(幾乎所有對象都分配在堆上),是垃圾回收(GC)的核心戰(zhàn)場 —— 我們常說的“GC回收內(nèi)存”,主要就是回收堆中不再被引用的對象。

關(guān)鍵特性

  • 線程共享:所有線程共用堆內(nèi)存,因此多線程創(chuàng)建對象時需考慮線程安全;
  • 生命周期:JVM啟動時創(chuàng)建,JVM退出時銷毀;
  • 堆的細分(GC優(yōu)化)
    為了提升GC效率,堆被進一步劃分為「新生代」和「老年代」(比例默認1:2,可通過-XX:NewRatio調(diào)整):
    堆
    ├── 新生代(Young Generation):存儲新創(chuàng)建的對象(短命對象)
    │   ├── Eden區(qū)(伊甸園區(qū)):新對象優(yōu)先分配到這里
    │   ├── Survivor0區(qū)(S0,F(xiàn)rom區(qū))
    │   └── Survivor1區(qū)(S1,To區(qū))
    └── 老年代(Old Generation):存儲存活時間長的對象(長命對象)
    • 新生代GC(Minor GC):Eden區(qū)滿時觸發(fā),回收短命對象,頻率高、速度快;
    • 老年代GC(Major GC/Full GC):老年代滿時觸發(fā),回收長命對象,頻率低、速度慢(會引發(fā)STW,影響性能)。

常見問題

  • OutOfMemoryError: Java heap space:堆內(nèi)存不足(比如創(chuàng)建大量大對象且不釋放引用,堆被占滿)。

代碼示例:觸發(fā)堆溢出

import java.util.ArrayList;
import java.util.List;
/**
 * 不斷創(chuàng)建大對象并保存引用,堆內(nèi)存被占滿,觸發(fā)OOM
 */
public class HeapOOMDemo {
    // 大對象:占用100KB內(nèi)存
    static class BigObject {
        private byte[] data = new byte[1024 * 100];
    }
    public static void main(String[] args) {
        List<BigObject> list = new ArrayList<>();
        try {
            while (true) {
                list.add(new BigObject()); // 保存對象引用,無法GC
            }
        } catch (OutOfMemoryError e) {
            System.out.println("堆溢出:" + e);
        }
    }
}

運行時添加JVM參數(shù)(限制堆大小):-Xms20m -Xmx20m(初始堆20M,最大堆20M),執(zhí)行結(jié)果:

堆溢出:java.lang.OutOfMemoryError: Java heap space

解釋:不斷創(chuàng)建BigObject并加入List,對象無法被GC回收,堆內(nèi)存被占滿,拋出堆溢出異常。

5. 元空間(Metaspace,JDK 8+)

核心理解

替代JDK 7及以前的「永久代(PermGen)」,用于存儲類的元數(shù)據(jù)(類的結(jié)構(gòu)信息、方法信息、常量池、靜態(tài)變量、注解等)。

關(guān)鍵特性

  • 線程共享:所有線程共用元空間;
  • 內(nèi)存來源:元空間使用「本地內(nèi)存」(操作系統(tǒng)的內(nèi)存),而非JVM堆內(nèi)存(永久代使用堆內(nèi)存),因此默認情況下元空間大小受操作系統(tǒng)內(nèi)存限制;
  • 可配置:可通過-XX:MetaspaceSize(初始大?。?code>-XX:MaxMetaspaceSize(最大大?。┫拗圃臻g;
  • GC回收:當(dāng)類被卸載(如自定義類加載器加載的類)時,元空間會回收該類的元數(shù)據(jù)。

常見問題

  • OutOfMemoryError: Metaspace:元空間不足(比如動態(tài)生成大量類,如反射、動態(tài)代理、CGLIB等,元數(shù)據(jù)占滿)。

代碼示例:觸發(fā)元空間溢出

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
/**
 * 動態(tài)生成大量類,元空間被占滿,觸發(fā)OOM(需引入CGLIB依賴)
 */
public class MetaspaceOOMDemo {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        try {
            while (true) {
                // 動態(tài)生成匿名子類
                enhancer.setSuperclass(Object.class);
                enhancer.setCallback((MethodInterceptor) (obj, method, args1, proxy) -> proxy.invokeSuper(obj, args1));
                enhancer.create(); // 生成新類,元數(shù)據(jù)存入元空間
            }
        } catch (OutOfMemoryError e) {
            System.out.println("元空間溢出:" + e);
        }
    }
}

運行時添加JVM參數(shù):-XX:MaxMetaspaceSize=10m(限制元空間最大10M),執(zhí)行結(jié)果:

元空間溢出:java.lang.OutOfMemoryError: Metaspace

解釋:CGLIB不斷動態(tài)生成新類,類的元數(shù)據(jù)占滿元空間,拋出元空間溢出異常。

6. 直接內(nèi)存(Direct Memory)

核心理解

不屬于JVM規(guī)范定義的內(nèi)存區(qū)域(是“堆外內(nèi)存”),但被頻繁使用 —— JVM通過Unsafe類或ByteBuffer.allocateDirect()分配直接內(nèi)存,用于提升IO性能(避免JVM堆和操作系統(tǒng)內(nèi)存之間的拷貝)。

關(guān)鍵特性

  • 內(nèi)存來源:操作系統(tǒng)的本地內(nèi)存,不受JVM堆大小限制(但受總物理內(nèi)存限制);
  • 訪問速度:比堆內(nèi)存快(減少內(nèi)存拷貝),但分配/回收成本更高;
  • 常見問題OutOfMemoryError: Direct buffer memory(直接內(nèi)存不足)。

示例:分配直接內(nèi)存

import java.nio.ByteBuffer;
/**
 * 分配大量直接內(nèi)存,觸發(fā)直接內(nèi)存溢出
 */
public class DirectMemoryOOMDemo {
    public static void main(String[] args) {
        int size = 1024 * 1024 * 100; // 100MB
        try {
            while (true) {
                // 分配直接內(nèi)存
                ByteBuffer buffer = ByteBuffer.allocateDirect(size);
            }
        } catch (OutOfMemoryError e) {
            System.out.println("直接內(nèi)存溢出:" + e);
        }
    }
}

運行時添加JVM參數(shù):-XX:MaxDirectMemorySize=200m(限制直接內(nèi)存最大200M),執(zhí)行結(jié)果:

直接內(nèi)存溢出:java.lang.OutOfMemoryError: Direct buffer memory

四、關(guān)鍵對比:線程私有 vs 線程共享區(qū)域

類型包含區(qū)域生命周期核心特點
線程私有程序計數(shù)器、虛擬機棧、本地方法棧與線程一致(線程創(chuàng)建則創(chuàng)建,線程銷毀則銷毀)無需GC回收(隨線程銷毀自動釋放)
線程共享堆、元空間與JVM一致(JVM啟動則創(chuàng)建,退出則銷毀)需GC回收(堆回收對象,元空間回收類元數(shù)據(jù))

五、理解Java內(nèi)存區(qū)域的核心意義

  1. 定位內(nèi)存問題:不同的內(nèi)存異常對應(yīng)不同的區(qū)域(比如StackOverflowError是棧問題,Java heap space是堆問題),理解內(nèi)存區(qū)域能快速定位問題根源;
  2. 優(yōu)化JVM性能:通過調(diào)整各區(qū)域的內(nèi)存參數(shù)(如-Xms/-Xmx調(diào)整堆大小,-Xss調(diào)整棧大?。m配業(yè)務(wù)場景,減少GC頻率和OOM概率;
  3. 理解GC原理:GC的核心是回收堆內(nèi)存,而堆的分代設(shè)計(新生代/老年代)直接影響GC策略,理解內(nèi)存區(qū)域是掌握GC的基礎(chǔ);
  4. 編寫高性能代碼:比如避免創(chuàng)建大量短命大對象(減少Minor GC)、避免無限遞歸(防止棧溢出)、合理使用直接內(nèi)存(提升IO性能)。

六、總結(jié)

Java內(nèi)存區(qū)域是JVM對運行時內(nèi)存的“功能分區(qū)管理”,核心是:

  • 線程私有區(qū)域為線程執(zhí)行提供基礎(chǔ)(程序計數(shù)器記錄執(zhí)行位置,棧為方法提供內(nèi)存);
  • 線程共享區(qū)域存儲共享數(shù)據(jù)(堆存對象,元空間存類信息);
  • 直接內(nèi)存是堆外優(yōu)化手段,提升IO性能。

理解每個區(qū)域的“存儲內(nèi)容、生命周期、異常類型”,是排查JVM內(nèi)存問題、優(yōu)化JVM性能的核心基礎(chǔ)。

到此這篇關(guān)于JAVA內(nèi)存區(qū)域示例詳解的文章就介紹到這了,更多相關(guān)java內(nèi)存區(qū)域內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot前后端分離實現(xiàn)個人博客系統(tǒng)

    SpringBoot前后端分離實現(xiàn)個人博客系統(tǒng)

    這篇文章主要為大家詳細介紹了使用springboot+mybatis+前端vue,使用前后端分離架構(gòu)實現(xiàn)的個人博客系統(tǒng),感興趣的小伙伴可以動手嘗試一下
    2022-06-06
  • linux環(huán)境下java程序打包成簡單的hello world輸出jar包示例

    linux環(huán)境下java程序打包成簡單的hello world輸出jar包示例

    這篇文章主要介紹了linux環(huán)境下java程序打包成簡單的hello world輸出jar包,結(jié)合簡單hello world輸出程序示例分析了Linux環(huán)境下的java可執(zhí)行jar包文件的生成相關(guān)操作技巧,需要的朋友可以參考下
    2019-11-11
  • MyBatis-plus中的模糊查詢解讀

    MyBatis-plus中的模糊查詢解讀

    這篇文章主要介紹了MyBatis-plus中的模糊查詢解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 對Java字符串與整形、浮點類型之間的相互轉(zhuǎn)換方法總結(jié)

    對Java字符串與整形、浮點類型之間的相互轉(zhuǎn)換方法總結(jié)

    今天小編就為大家分享一篇對Java字符串與整形、浮點類型之間的相互轉(zhuǎn)換方法總結(jié),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • Java自定義Enum的實現(xiàn)示例

    Java自定義Enum的實現(xiàn)示例

    Java中的自定義Enum類型是一種特殊的類,用于表示固定數(shù)量的常量值,本文主要介紹了Java自定義Enum的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • struts2框架的登錄制作圖文教程

    struts2框架的登錄制作圖文教程

    下面小編就為大家?guī)硪黄猻truts2框架的登錄制作圖文教程。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • 使用Sharding-JDBC對數(shù)據(jù)進行分片處理詳解

    使用Sharding-JDBC對數(shù)據(jù)進行分片處理詳解

    這篇文章主要介紹了使用Sharding-JDBC對數(shù)據(jù)進行分片處理詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java中的Semaphore如何使用

    Java中的Semaphore如何使用

    Semaphore實際上是一種共享鎖,因為它允許多個線程并發(fā)獲取共享的資源,在Semaphore對象創(chuàng)建時必須設(shè)置可用令牌的初始數(shù)量permits,用于控制并發(fā)時同時獲取資源權(quán)限的線程數(shù)量,這篇文章主要介紹了Java中的Semaphore如何使用,需要的朋友可以參考下
    2022-06-06
  • java實現(xiàn)分布式鎖的常用三種方式

    java實現(xiàn)分布式鎖的常用三種方式

    本文主要介紹了java實現(xiàn)分布式鎖,一般有這3種方式,基于數(shù)據(jù)庫實現(xiàn)的分布式鎖、基于Redis實現(xiàn)的分布式鎖和基于Zookeeper實現(xiàn)的分布式鎖,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • Java中GC的工作原理詳細介紹

    Java中GC的工作原理詳細介紹

    這篇文章主要介紹了Java中GC的工作原理詳細介紹的相關(guān)資料,需要的朋友可以參考下
    2017-03-03

最新評論

兰州市| 特克斯县| 石屏县| 会东县| 凤山市| 虎林市| 永川市| 怀来县| 九寨沟县| 福泉市| 汤原县| 南阳市| 内黄县| 江陵县| 休宁县| 孝昌县| 连城县| 五华县| 连平县| 远安县| 寿宁县| 珲春市| 昌邑市| 浏阳市| 瓦房店市| 舒城县| 拜泉县| 通州市| 泽库县| 灵武市| 郴州市| 孟连| 郁南县| 安平县| 兴隆县| 昭觉县| 太仓市| 合山市| 陵川县| 抚顺县| 伊川县|