JVM筆記----Java虛擬機內部結構介紹


  Java與c++之間有一堵由內存動態分配和垃圾收集技術所圍成的“高牆”,牆外的人想進去,牆里面的人卻想出來。

                                 —— 《深入理解Java虛擬機》 周志明

 

  對於c++來說 , 在內存管理領域,他們既是擁有最高權利的皇帝,又是從事最基礎工作的勞動人民。他們擁有每一個對象的

所有權,又背負着維護每一個對象的責任。

  而對於Java程序員來說,在JVM的幫助下,不再需要為每一個new 操作去寫配對的delete / free 代碼,不容易出現內存泄漏

和內存溢出的問題。

  那么就然我們來一探JVM的底層結構吧~

 

          

 

上圖就是JVM的結構啦~ 那么下面就讓我來 一 一 介紹 每塊區域的職責和特點

  

  

  當我們把java程序寫出來的時候,首先要對它進行編譯才可以運行,比如上圖的Math類,我們要首先用javac指令

把它編譯生成字節碼文件( .class ) , 然后就可以運行了,而運行時的內存管理就依賴於JVM,由JVM對我們的內存

進行管理。

 

  程序計數器:

   

        想必學過計算機組成原理的同學對程序計數器都不陌生吧~ 它負責記錄我們的代碼運行到哪一行,以及負責一些流程控制。

  

  字節碼解釋器工作時會通過改變計數器的值來選去下一條指令,分支,循環,跳轉,異常處理,線程恢復都需要計數器。

  

  每條線程都需要一個獨立計數器,各線程計數器互不影響,這類內存區域稱為“線程私有”內存。

 

  棧(線程):

  

 線程私有,生命周期與線程相同。

 

  每個方法在執行的時候會創建一個棧幀 用於存儲  局部變量表 、 操作數棧 、 動態鏈接 、 方法出口

     

    每一個方法從調用直到執行完成的過程,就對應一個棧幀在虛擬機中入棧到出棧的過程。

  

  局部變量表: 存放各種基本數據類型 ( boolean , byte , char , short , int , float , long , double ) 沒有 String!

        對象引用 ( 指向對象起始地址的指針 )

        return Address 類型 (指向一條字節碼指令的地址)

        

      它有哪些異常呢? 有:線程請求的棧深度大於JVM所允許,StackOverflowError

                若棧可以動態擴展,無發申請到足夠內存時,OutOfMemoryError

   

   本地方法棧: 

      與虛擬機棧區別:虛擬機棧為JVM執行Java方法服務

              方法棧為JVM使用到的Native方法服務

        

      也會拋出StackOverflowError, OutOfMemoryError

 堆:

      內存最大 被所有線程共享 

    幾乎所有的對象實例和數組都要在堆中分配內存(除了靜態等)

    若在堆中沒有內存完成實例分配,且堆無法擴展時,拋出OutOfMemoryError

  方法區:

   線程共享

    

    用於存儲類信息,常量,靜態變量,編譯后的代碼

    

    垃圾收集很少出現

  

  運行時常量池:

     方法區的一部分

    存放編譯期生成的各種字面量和符號引號(常量池)

    這部分內容在類加載后進入方法區的運行時常量池中存放

 

 直接內存:

     不是JVM運行時數據區的一部分,也不是JVM規范中定義的內存區域

 

那么今天的JVM就介紹到這里~

下一次我會介紹JVM是如何創建對象的哦~

  

    

 

    

 

 

                         


免責聲明!

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



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