中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解Java虛擬機運行時數據區域

發布時間:2021-11-17 14:02:26 來源:億速云 閱讀:147 作者:柒染 欄目:軟件技術

這期內容當中小編將會給大家帶來有關如何理解Java虛擬機運行時數據區域,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

一、程序計數器(Program Counter Register)

  • 當前線程所執行的字節碼行號指示器(邏輯)

  • 通過改變計數器的值來選取下一條需要執行的字節碼指令

  • 和線程一對一的關系,即“線程私有”

  • 對 Java 方法計數,如果是 Native 方法則計數器值為 Undefined

  • 只是計數,不會發生內存泄漏

二、Java 虛擬機棧

每個 Java 方法在執行的同時會創建一個棧幀用于存儲局部變量表、操作數棧、常量池引用等信息。從方法調用直至執行完成的過程,就對應著一個棧幀在 Java 虛擬機棧中入棧和出棧的過程。

可以通過 -Xss 這個虛擬機參數來指定每個線程的 Java 虛擬機棧內存大小:

java -Xss512M HackTheJava

該區域可能拋出以下異常:

  • 當線程請求的棧深度超過最大值,會拋出 StackOverflowError 異常;

  • 棧進行動態擴展時如果無法申請到足夠內存,會拋出 OutOfMemoryError 異常。

局部變量表和操作數棧

  • 局部變量表:包含方法執行過程中的所有變量

  • 操作數棧:入棧、出棧、復制、交換、產生消費變量

    public class JVMTest {
      public static int add(int a ,int b) {
          int c = 0;
          c = a + b;
          return c;
      }
    }
javap -verbose JVMTest

三、本地方法棧

本地方法棧與 Java 虛擬機棧類似,它們之間的區別只不過是本地方法棧為本地方法服務。

本地方法一般是用其它語言(C、C++ 或匯編語言等)編寫的,并且被編譯為基于本機硬件和操作系統的程序,對待這些方法需要特別處理。

四、堆

所有對象都在這里分配內存,是垃圾收集的主要區域(”GC 堆”)。

現代的垃圾收集器基本都是采用分代收集算法,其主要的思想是針對不同類型的對象采取不同的垃圾回收算法。可以將堆分成兩塊:

  • 新生代(Young Generation)

  • 老年代(Old Generation)

堆不需要連續內存,并且可以動態增加其內存,增加失敗會拋出 OutOfMemoryError 異常。

可以通過 -Xms 和 -Xmx 這兩個虛擬機參數來指定一個程序的堆內存大小,第一個參數設置初始值,第二個參數設置最大值。

java -Xms1M -Xmx2M HackTheJava

1. Java 內存分配策略

  • 靜態存儲:編譯時確定每個數據目標在運行時的存儲空間需求

  • 棧式存儲:數據區需求在編譯時未知,運行時模塊入口前確定

  • 堆式存儲:編譯時或運行時模塊入口都無法確定,動態分配

2. 問題一:堆和棧的聯系

引用對象、數組時,棧里定義變量保存堆中目標的首地址。

3. 問題二:棧和堆的區別

①. 物理地址

  • 堆的物理內存分配是不連續的;

  • 棧的物理內存分配是連續的

②. 分配內存

  • 堆是不連續的,分配的內存是在運行期確定的,大小不固定;

  • 棧是連續的,分配的內存在編譯器就已經確定,大小固定

③. 存放內容

  • 堆中存放的是對象和數組,關注的是數據的存儲;

  • 棧中存放局部變量,關注的是程序方法的執行

④. 是否線程私有

  • 堆內存中的對象對所有線程可見,可被所有線程訪問;

  • 棧內存屬于某個線程私有的

⑤. 異常

  • 棧擴展失敗,會拋出 StackOverflowError;

  • 堆內存不足,會拋出 OutOfMemoryError

五、方法區

用于存放已被加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。

和堆一樣不需要連續的內存,并且可以動態擴展,動態擴展失敗一樣會拋出 OutOfMemoryError 異常。

對這塊區域進行垃圾回收的主要目標是對常量池的回收和對類的卸載,但是一般比較難實現。

HotSpot 虛擬機把它當成永久代來進行垃圾回收。但很難確定永久代的大小,因為它受到很多因素影響,并且每次 Full GC 之后永久代的大小都會改變,所以經常會拋出 OutOfMemoryError 異常。為了更容易管理方法區,從 JDK 1.8 開始,移除永久代,并把方法區移至元空間,它位于本地內存中,而不是虛擬機內存中。

方法區是一個 JVM 規范,永久代與元空間都是其一種實現方式。在 JDK 1.8 之后,原來永久代的數據被分到了堆和元空間中。元空間存儲類的元信息,靜態變量和常量池等放入堆中。

1. 元空間(MetaSpace)與永久代(PermGen)的區別

元空間使用本地內存,而永久代使用 JVM 的內存。

2. 元空間(MetaSpace)相比永久代(PermGen)的優勢

  • 字符串常量池存在永久代中,容易出現性能問題和內存溢出

  • 類和方法的信息大小難以確定,給永久代的大小指定帶來困難

  • 永久代會為 GC 帶來不必要的復雜性

六、運行時常量池

運行時常量池是方法區的一部分。

Class 文件中的常量池(編譯器生成的字面量和符號引用)會在類加載后被放入這個區域。

除了在編譯期生成的常量,還允許動態生成,例如 String 類的 intern()。

直接內存

在 JDK 1.4 中新引入了 NIO 類,它可以使用 Native 函數庫直接分配堆外內存,然后通過 Java 堆里的 DirectByteBuffer 對象作為這塊內存的引用進行操作。這樣能在一些場景中顯著提高性能,因為避免了在堆內存和堆外內存來回拷貝數據。

七、JVM常見參數

如何理解Java虛擬機運行時數據區域

上述就是小編為大家分享的如何理解Java虛擬機運行時數據區域了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宁乡县| 襄汾县| 潮州市| 收藏| 塔城市| 祥云县| 桐柏县| 科技| 阿坝县| 辽宁省| 陇南市| 邹平县| 丽江市| 津南区| 湖南省| 宁强县| 灵丘县| 肥西县| 博罗县| 博爱县| 泸溪县| 高青县| 蚌埠市| 大同县| 堆龙德庆县| 金乡县| 礼泉县| 连云港市| 明光市| 金山区| 河西区| 措勤县| 桐庐县| 咸阳市| 乌什县| 电白县| 虎林市| 淳化县| 根河市| 济源市| 仲巴县|