Java中JVM內(nèi)存結(jié)構(gòu)及各區(qū)域功能詳解

jvm內(nèi)存結(jié)構(gòu)包含程序計數(shù)器、虛擬機、本地方法棧、、方法區(qū)、運行時常量池和直接內(nèi)存。程序計數(shù)器記錄線程執(zhí)行位置,每個線程獨立;Java虛擬機棧存儲方法調(diào)用時的局部變量、操作數(shù)棧等信息,線程私有;本地方法棧服務(wù)于本地方法調(diào)用;java堆是所有線程共享的區(qū)域,用于存放對象實例并由垃圾回收器管理;方法區(qū)存儲類信息、常量池、靜態(tài)變量等,jdk 8后由元空間實現(xiàn);運行時常量池是方法區(qū)的一部分,保存編譯期生成的字面量和符號引用;直接內(nèi)存不屬于jvm運行時數(shù)據(jù)區(qū),但可通過nio進行高效io操作。垃圾回收分為標(biāo)記、清除、整理三步,常見算法包括標(biāo)記-清除、復(fù)制、標(biāo)記-整理和分代收集。常用jvm調(diào)優(yōu)參數(shù)包括設(shè)置堆大小、新生代比例及選擇垃圾回收器等;監(jiān)控工具如jstat、jinfo、visualvm等可用于分析jvm運行狀態(tài)。

Java中JVM內(nèi)存結(jié)構(gòu)及各區(qū)域功能詳解

Java虛擬機(JVM)的內(nèi)存結(jié)構(gòu)是理解Java程序運行機制的關(guān)鍵。它決定了程序如何存儲數(shù)據(jù)、執(zhí)行指令以及進行垃圾回收。簡單來說,JVM內(nèi)存結(jié)構(gòu)就像一個組織嚴(yán)密的倉庫,不同的區(qū)域存放著不同的物品,各司其職,共同保障程序的順利運行。

Java中JVM內(nèi)存結(jié)構(gòu)及各區(qū)域功能詳解

程序計數(shù)器(Program Counter register,PC Register) 每個線程都有一個獨立的程序計數(shù)器,它是一個指向下一條要執(zhí)行的指令的指針。可以把它想象成一個書簽,記錄著你讀到哪一頁了。對于本地方法,程序計數(shù)器則為空(undefined)。

Java中JVM內(nèi)存結(jié)構(gòu)及各區(qū)域功能詳解

Java虛擬機棧(Java Virtual Machine Stacks) 同樣是線程私有的,它描述的是Java方法執(zhí)行的內(nèi)存模型:每個方法在執(zhí)行的同時都會創(chuàng)建一個棧幀(Stack Frame)用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息。 棧幀就像一個臨時的工作臺,方法執(zhí)行完畢,工作臺也就被清理干凈了。局部變量表存放著方法中的局部變量,包括基本數(shù)據(jù)類型、對象引用等。

Java中JVM內(nèi)存結(jié)構(gòu)及各區(qū)域功能詳解

本地方法棧(Native Method Stack) 與Java虛擬機棧類似,只不過它服務(wù)于本地方法。有些本地方法(比如用C/c++編寫的)可能會直接操作操作系統(tǒng)底層的資源。

Java堆(Java Heap) 這是JVM中最大的一塊內(nèi)存區(qū)域,所有線程共享。幾乎所有的對象實例都在這里分配內(nèi)存。Java堆也是垃圾收集器管理的主要區(qū)域,因此也被稱為“GC堆”(Garbage Collected Heap)。 堆就像一個巨大的停車場,所有的車輛(對象)都停放在這里,垃圾回收器負責(zé)清理那些廢棄的車輛。

方法區(qū)(Method Area) 也是所有線程共享的區(qū)域,用于存儲已被虛擬機加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)。 很多人把方法區(qū)稱為“永久代”(Permanent Generation),但實際上兩者并不等價,只是在HotSpot虛擬機中,習(xí)慣使用永久代來實現(xiàn)方法區(qū)。在JDK 8及以后,永久代已經(jīng)被元空間(Metaspace)取代,元空間使用的是本地內(nèi)存,而不是JVM內(nèi)存。

運行時常量池(Runtime Constant Pool) 是方法區(qū)的一部分。 class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池(Constant Pool table),用于存放編譯期生成的各種字面量和符號引用,這部分內(nèi)容將在類加載后進入方法區(qū)的運行時常量池中存放。

直接內(nèi)存(Direct Memory) 雖然不屬于JVM運行時數(shù)據(jù)區(qū)的一部分,但也會被頻繁使用。 例如,NIO(New input/Output)就允許Java程序直接分配堆外內(nèi)存,避免了在Java堆和本地內(nèi)存之間來回復(fù)制數(shù)據(jù),從而提高性能。

JVM如何進行垃圾回收(GC)? 垃圾回收是JVM自動進行的內(nèi)存管理過程,主要目的是回收不再使用的對象,釋放內(nèi)存空間,防止內(nèi)存泄漏。 不同的垃圾回收器采用不同的算法,但大致可以分為以下幾個步驟:

  1. 標(biāo)記: 找出所有存活的對象。
  2. 清除: 回收被標(biāo)記為垃圾的對象所占用的內(nèi)存空間。
  3. 整理: 整理內(nèi)存碎片,提高內(nèi)存利用率。

常見的垃圾回收算法包括:

  • 標(biāo)記-清除算法(Mark-Sweep)
  • 復(fù)制算法(Copying)
  • 標(biāo)記-整理算法(Mark-Compact)
  • 分代收集算法(Generational Collection

JVM調(diào)優(yōu)有哪些常用參數(shù)? JVM調(diào)優(yōu)是一個復(fù)雜的過程,需要根據(jù)具體的應(yīng)用場景進行調(diào)整。 一些常用的JVM參數(shù)包括:

  • -Xms: 設(shè)置JVM初始堆大小。
  • -Xmx: 設(shè)置JVM最大堆大小。
  • -Xmn: 設(shè)置新生代大小。
  • -XX:SurvivorRatio: 設(shè)置Eden區(qū)和Survivor區(qū)的比例。
  • -XX:+UseG1GC: 使用G1垃圾回收器。
  • -XX:MaxGCPauseMillis: 設(shè)置最大GC停頓時間。

如何監(jiān)控JVM的運行狀態(tài)? 監(jiān)控JVM的運行狀態(tài)對于診斷性能問題至關(guān)重要。 常用的監(jiān)控工具包括:

  • jstat: JVM統(tǒng)計監(jiān)測工具。
  • jinfo: JVM配置信息工具。
  • jmap: JVM內(nèi)存映像工具。
  • jstack: JVM堆棧跟蹤工具。
  • VisualVM: 一款圖形化的JVM監(jiān)控工具。

理解JVM內(nèi)存結(jié)構(gòu)和垃圾回收機制,可以幫助我們編寫更高效、更穩(wěn)定的Java程序。

立即學(xué)習(xí)Java免費學(xué)習(xí)筆記(深入)”;

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊10 分享