JVM工作原理淺析


JVM(JavaVirtualMachine,Java虛擬機)是JRE的一部分。它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。JVM有自己完善的硬件架構,如處理器、堆棧、寄存器等,還具有相應的指令系統。Java語言最重要的特點就是跨平台運行。使用JVM就是為了支持與操作系統無關,實現跨平台。

大多數 JVM 將內存區域划分為 Method Area(Non-Heap)(方法區) ,Heap(堆) , Program Counter Register(程序計數器) ,   VM Stack(虛擬機棧,也有翻譯成JAVA 方法棧的),Native Method Stack  ( 本地方法棧 ),其中Method Area 和  Heap 是線程共享的  ,VM Stack,Native Method Stack  和Program Counter Register  是非線程共享的。為什么分為 線程共享和非線程共享的呢?請繼續往下看。

首先我們熟悉一下一個一般性的 Java 程序的工作過程。一個 Java 源程序文件,會被編譯為字節碼文件(以 class 為擴展名),每個java程序都需要運行在自己的JVM上,然后告知 JVM 程序的運行入口,再被 JVM 通過字節碼解釋器加載運行。那么程序開始運行后,都是如何涉及到各內存區域的呢?

概括地說來,JVM初始運行的時候都會分配好 Method Area(方法區) 和Heap(堆) ,而JVM 每遇到一個線程,就為其分配一個 Program Counter Register(程序計數器) ,   VM Stack(虛擬機棧)和Native Method Stack  (本地方法棧), 當線程終止時,三者(虛擬機棧,本地方法棧和程序計數器)所占用的內存空間也會被釋放掉。這也是為什么我把內存區域分為線程共享和非線程共享的原因,非線程共享的那三個區域的生命周期與所屬線程相同,而線程共享的區域與JAVA程序運行的生命周期相同,所以這也是系統垃圾回收的場所只發生在線程共享的區域(實際上對大部分虛擬機來說知發生在Heap上)的原因。

內存區中的方法區域存放了所加載的類的信息(名稱、修飾符等)、類中的靜態變量、類中定義為final類型的常量、類中的Field信息、類中的方法信息,當開發人員在程序中通過Class對象中的getName、isInterface等方法來獲取信息時,這些數據都來源於方法區域,同時方法區域也是全局共享的,在一定的條件下它也會被GC,當方法區域需要使用的內存超過其允許的大小時,會拋出OutOfMemory的錯誤信息。

                                                                                                                                 JVM 內存模型圖

 

 

 

方法區用於存儲JVM加載的類信息、常量、靜態變量、以及編譯器編譯后的代碼等數據,是線程隔離的
運行時數據區可以分成 方法區、 堆、 棧、 程序計數器、 本地方法棧。



總結如下:
  一、JVM內存分為堆、方法區、虛擬機棧、本地方法棧、程序計數器五個部分。

  二、堆和方法區是線程共享的,虛擬機棧、本地方法棧和程序計數器是線程隔離的。

  三、1.堆主要是存放對象實例的也包括數組,是垃圾管理的主要作用區。
      2.方法區主要是存儲類信息、常量、靜態變量,方法區有個別名叫Non-Heap用於和堆區分開,一般來說方法區的垃圾回收“成績”比較難令人滿意;
  3.虛擬機棧描述的是Java方法執行的內存模型:每個方法被執行的時候都會同時創建一個棧幀(StackFrame)用於存儲局部變量表、操作棧、動態鏈接、方法出口 等信息。每一個方法被調用直至執行完成的過程,就對應着一個棧   幀在虛擬機棧中從入棧到出棧的過程。
  4.本地方法棧和虛擬機棧非常相似,只不過本地方法棧是為Java使用到的Native方法服務的。
  5.程序計數器是一塊較小的內存空間,是當前線程所執行的字節碼的行號指示器。字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這 個計數器來完成。





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM