深入淺出:JVM內存結構

什麼是JVM?

JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用於計算設備的規範,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。

爲什麼要有JVM?

引入Java語言虛擬機後,Java語言在不同平臺上運行時不需要重新編譯。Java語言使用Java虛擬機屏蔽了與具體平臺相關的信息,使得Java語言編譯程序只需生成在Java虛擬機上運行的目標代碼(字節碼),就可以在多種平臺上不加修改地運行。

JVM內存結構有哪些?

在這裏插入圖片描述

堆(Heap)

線程共享。所有的對象實例以及數組都要在堆上分配。回收器主要管理的對象

  • 控制參數
    -Xms設置堆的最小空間大小。-Xmx設置堆的最大空間大小。-XX:NewSize設置新生代最小空間大小。-XX:MaxNewSize設置新生代最小空間大小。
  • 垃圾回收 此區域是垃圾回收的主要操作區域。
  • 異常情況 如果在堆中沒有內存完成實例分配,並且堆也無法再擴展時,將會拋出OutOfMemoryError 異常

方法區(Method Area)

線程共享。存儲類信息、常量、靜態變量、即時編譯器編譯後的代碼

  • 控制參數
    -XX:PermSize 設置最小空間 -XX:MaxPermSize 設置最大空間。
  • 垃圾回收
    對此區域會涉及但是很少進行垃圾回收。這個區域的內存回收目標主要是針對常量池的回收和對類型的卸載,一般來說這個區域的回收“成績”比較難以令人滿意。
  • 異常情況 根據Java 虛擬機規範的規定, 當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError。

方法棧(JVM Stack)

線程私有。存儲局部變量表、操作棧、動態鏈接、方法出口,對象指針

  • 控制參數
    -Xss控制每個線程棧的大小。
  • 異常情況 在Java 虛擬機規範中,對這個區域規定了兩種異常狀況:
    • StackOverflowError: 異常線程請求的棧深度大於虛擬機所允許的深度時拋出;

    • OutOfMemoryError 異常: 虛擬機棧可以動態擴展,當擴展時無法申請到足夠的內存時會拋出。

本地方法棧(Native Method Stack)

線程私有。爲虛擬機使用到的Native方法服務。如Java使用c或者c++編寫的接口服務時,代碼在此區運行。

  • 控制參數 在Sun JDK中本地方法棧和方法棧是同一個,因此也可以用-Xss控制每個線程的大小。
  • 異常情況 與虛擬機棧一樣,本地方法棧區域也會拋出StackOverflowError 和OutOfMemoryError異常。

程序計數器(Program Counter Register)

線程私有。有些文章也翻譯成PC寄存器(PCRegister),同一個東西。它可以看作是當前線程所執行的字節碼的行號指示器。指向下一條要執行的指令。

  • 異常情況 此內存區域是唯一一個在Java 虛擬機規範中沒有規定任何OutOfMemoryError 情況的區域。

總結

每個Java程序都離不開Java虛擬機,Java程序的運行依靠具體Java虛擬機實例。在Java虛擬機規範中,分別用子系統、內存區、數據類型以及指令這幾個術語來描述的。這些組成部分一起展示出一個抽象化的虛擬機內部的抽象體系結構。

對於Java運行時涉及到的存儲區域主要包括程序計數器、Java虛擬機棧、本地方法棧、java堆、方法區以及直接內存等等。對於每個部分,都有其使用的條件。程序計數器主要是取下一條指令,在Java裏面主要是取下一條指令的字節碼文件;Java虛擬機棧主要是利用棧先進後出的特性存儲局部變量表,動態鏈接等,主要包括堆內存和棧內存,對於程序員內存分析而言是特別重要的。本地方法棧與上邊的棧基本作用差不多,只不過這裏是爲Java方法而服務。Java堆是內存管理中最大的一塊,所有的線程共享這一塊內容,同時該部分也是垃圾收集器的主要區域。

虛擬機的垃圾回收機制是完善的,動態內存分配和回收是比較成熟的,在內存管理機制中,大部分都不需要我們考慮內存回收,只有Java堆和方法區需要我們考慮處理內存問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章