亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

JVM運行原理是怎么樣的呢

發布時間:2021-10-23 16:34:05 來源:億速云 閱讀:129 作者:柒染 欄目:云計算

JVM運行原理是怎么樣的呢,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

1.JVM簡析:

     作為一名Java使用者,掌握JVM的體系結構也是很有必要的。

     說起Java,我們首先想到的是Java編程語言,然而事實上,Java是一種技術,它由四方面組成:Java編程語言、Java類文件格式、Java虛擬機和Java應用程序接口(Java API)。它們的關系如下圖所示:

JVM運行原理是怎么樣的呢

     Java平臺由Java虛擬機和Java應用程序接口搭建,Java語言則是進入這個平臺的通道,用Java語言編寫并編譯的程序可以運行在這個平臺上。這個平臺的結構如下圖所示:     

JVM運行原理是怎么樣的呢

運行期環境代表著Java平臺,開發人員編寫Java代碼(.java文件),然后將之編譯成字節碼(.class文件),再然后字節碼被裝入內存,一旦字節碼進入虛擬機,它就會被解釋器解釋執行,或者是被即時代碼發生器有選擇的轉換成機器碼執行。

     JVM在它的生存周期中有一個明確的任務,那就是運行Java程序,因此當Java程序啟動的時候,就產生JVM的一個實例;當程序運行結束的時候,該實例也跟著消失了。     在Java平臺的結構中, 可以看出,Java虛擬機(JVM) 處在核心的位置,是程序與底層操作系統和硬件無關的關鍵。它的下方是移植接口,移植接口由兩部分組成:適配器和Java操作系統, 其中依賴于平臺的部分稱為適配器;JVM 通過移植接口在具體的平臺和操作系統上實現;在JVM 的上方是Java的基本類庫和擴展類庫以及它們的API, 利用Java API編寫的應用程序(application) 和小程序(Java applet) 可以在任何Java平臺上運行而無需考慮底層平臺, 就是因為有Java虛擬機(JVM)實現了程序與操作系統的分離,從而實現了Java 的平臺無關性。

     下面我們從JVM的基本概念和運過程程這兩個方面入手來對它進行深入的研究。

2.JVM基本概念

(1) 基本概念:

     JVM是可運行Java代碼的假想計算機 ,包括一套字節碼指令集、一組寄存器、一個棧、一個垃圾回收,堆 和 一個存儲方法域。JVM是運行在操作系統之上的,它與硬件沒有直接的交互。

(2) 運行過程:

     我們都知道Java源文件,通過編譯器,能夠生產相應的.Class文件,也就是字節碼文件,而字節碼文件又通過Java虛擬機中的解釋器,編譯成特定機器上的機器碼 。

也就是如下:

     ① Java源文件—->編譯器—->字節碼文件

     ② 字節碼文件—->JVM—->機器碼

     每一種平臺的解釋器是不同的,但是實現的虛擬機是相同的,這也就是Java為什么能夠跨平臺的原因了 ,當一個程序從開始運行,這時虛擬機就開始實例化了,多個程序啟動就會存在多個虛擬機實例。程序退出或者關閉,則虛擬機實例消亡,多個虛擬機實例之間數據不能共享。

(3) 三種JVM:

     ① Sun公司的HotSpot;

     ② BEA公司的JRockit;

     ③ IBM公司的J9 JVM;

     在JDK1.7及其以前我們所使用的都是Sun公司的HotSpot,但由于Sun公司和BEA公司都被oracle收購,jdk1.8將采用Sun公司的HotSpot和BEA公司的JRockit兩個JVM中精華形成jdk1.8的JVM。

3.JVM的體系結構

JVM運行原理是怎么樣的呢

(1) Class Loader類加載器

       負責加載 .class文件,class文件在文件開頭有特定的文件標示,并且ClassLoader負責class文件的加載等,至于它是否可以運行,則由Execution Engine決定。

① 定位和導入二進制class文件

② 驗證導入類的正確性

③ 為類分配初始化內存

④ 幫助解析符號引用.

(2) Native Interface本地接口:

         本地接口的作用是融合不同的編程語言為Java所用,它的初衷是融合C/C++程序,Java誕生的時候C/C++橫行的時候,要想立足,必須有調用C/C++程序,于是就在內存中專門開辟了一塊區域處理標記為native的代碼,它的具體作法是Native Method Stack中登記native方法,在Execution Engine執行時加載native libraies。

         目前該方法使用的越來越少了,除非是與硬件有關的應用,比如通過Java程序驅動打印機,或者Java系統管理生產設備,在企業級應用中已經比較少見。

         因為現在的異構領域間的通信很發達,比如可以使用Socket通信,也可以使用Web Service等。

(3) Execution Engine 執行引擎:執行包在裝載類的方法中的指令,也就是方法。

(4) Runtime data area 運行數據區:

      虛擬機內存或者Jvm內存,沖整個計算機內存中開辟一塊內存存儲Jvm需要用到的對象,變量等,運行區數據有分很多小區,分別為:方法區,虛擬機棧,本地方法棧,堆,程序計數器。

4.JVM數據運行區詳解(棧管運行,堆管存儲):

     說明:JVM調優主要就是優化 Heap堆 和 Method Area 方法區。

JVM運行原理是怎么樣的呢

(1) Native Method Stack本地方法棧

         它的具體做法是Native Method Stack中登記native方法,在Execution Engine執行時加載native libraies。

(2) PC Register程序計數器

         每個線程都有一個程序計算器,就是一個指針,指向方法區中的方法字節碼(下一個將要執行的指令代碼),由執行引擎讀取下一條指令,是一個非常小的內存空間,幾乎可以忽略不記。

(3) Method Area方法區

         方法區是被所有線程共享,所有字段和方法字節碼,以及一些特殊方法如構造函數,接口代碼也在此定義。簡單說,所有定義的方法的信息都保存在該區域,此區域屬于共享區間。

         靜態變量+常量+類信息+運行時常量池存在方法區中,實例變量存在堆內存中。

(4) Stack 棧

     ① 棧是什么

         棧也叫棧內存,主管Java程序的運行,是在線程創建時創建,它的生命期是跟隨線程的生命期,線程結束棧內存也就釋放,對于棧來說不存在垃圾回收問題,只要線程一結束該棧就Over,生命周期和線程一致,是線程私有的。

          基本類型的變量和對象的引用變量都是在函數的棧內存中分配。

     ② 棧存儲什么?

     棧幀中主要保存3類數據:

          本地變量(Local Variables):輸入參數和輸出參數以及方法內的變量;

          棧操作(Operand Stack):記錄出棧、入棧的操作;

          棧幀數據(Frame Data):包括類文件、方法等等。

     ③ 棧運行原理

     棧中的數據都是以棧幀(Stack Frame)的格式存在,棧幀是一個內存區塊,是一個數據集,是一個有關方法和運行期數據的數據集,當一個方法A被調用時就產生了一個棧幀F1,并被壓入到棧中,A方法又調用了B方法,于是產生棧幀F2也被壓入棧,B方法又調用了C方法,于是產生棧幀F3也被壓入棧…… 依次執行完畢后,先彈出后進......F3棧幀,再彈出F2棧幀,再彈出F1棧幀。

     遵循“先進后出”/“后進先出”原則。

(5) Heap 堆

     堆這塊區域是JVM中最大的,應用的對象和數據都是存在這個區域,這塊區域也是線程共享的,也是 gc 主要的回收區,一個 JVM 實例只存在一個堆類存,堆內存的大小是可以調節的。類加載器讀取了類文件后,需要把類、方法、常變量放到堆內存中,以方便執行器執行,堆內存分為三部分:

JVM運行原理是怎么樣的呢

       新生區是類的誕生、成長、消亡的區域,一個類在這里產生,應用,最后被垃圾回收器收集,結束生命。新生區又分為兩部分:伊甸區(Eden space)和幸存者區(Survivor pace),所有的類都是在伊甸區被new出來的。幸存區有兩個:0區(Survivor 0 space)和1區(Survivor 1 space)。當伊甸園的空間用完時,程序又需要創建對象,JVM的垃圾回收器將對伊甸園進行垃圾回收(Minor GC),將伊甸園中的剩余對象移動到幸存0區。若幸存0區也滿了,再對該區進行垃圾回收,然后移動到1區。那如果1去也滿了呢?再移動到養老區。若養老區也滿了,那么這個時候將產生Major GC(FullGCC),進行養老區的內存清理。若養老區執行Full GC 之后發現依然無法進行對象的保存,就會產生OOM異常“OutOfMemoryError”。

     如果出現java.lang.OutOfMemoryError: Java heap space異常,說明Java虛擬機的堆內存不夠。原因有二:

    a.Java虛擬機的堆內存設置不夠,可以通過參數-Xms、-Xmx來調整。

     b.代碼中創建了大量大對象,并且長時間不能被垃圾收集器收集(存在被引用)。

         養老區用于保存從新生區篩選出來的 JAVA 對象,一般池對象都在這個區域活躍。

         永久存儲區是一個常駐內存區域,用于存放JDK自身所攜帶的 Class,Interface 的元數據,也就是說它存儲的是運行環境必須的類信息,被裝載進此區域的數據是不會被垃圾回收器回收掉的,關閉 JVM 才會釋放此區域所占用的內存。

     如果出現java.lang.OutOfMemoryError: PermGen space,說明是Java虛擬機對永久代Perm內存設置不夠。原因有二:

     a. 程序啟動需要加載大量的第三方jar包。例如:在一個Tomcat下部署了太多的應用。

     b. 大量動態反射生成的類不斷被加載,最終導致Perm區被占滿。

     說明:

     Jdk1.6及之前:常量池分配在永久代 。

     Jdk1.7:有,但已經逐步“去永久代” 。

     Jdk1.8及之后:無(java.lang.OutOfMemoryError: PermGen space,這種錯誤將不會出現在JDK1.8中)。

JVM運行原理是怎么樣的呢

     說明:方法區和堆內存的異議:

     實際而言,方法區和堆一樣,是各個線程共享的內存區域,它用于存儲虛擬機加載的:類信息+普通常量+靜態常量+編譯器編譯后的代碼等等,雖然JVM規范將方法區描述為堆的一個邏輯部分,但它卻還有一個別名叫做Non-Heap(非堆),目的就是要和堆分開。

     對于HotSpot虛擬機,很多開發者習慣將方法區稱之為“永久代(Parmanent Gen)”,但嚴格本質上說兩者不同,或者說使用永久代來實現方法區而已,永久代是方法區的一個實現,jdk1.7的版本中,已經將原本放在永久代的字符串常量池移走。

     常量池(Constant Pool)是方法區的一部分,Class文件除了有類的版本、字段、方法、接口等描述信息外,還有一項信息就是常量池,這部分內容將在類加載后進入方法區的運行時常量池中存放。

5.堆內存調優簡介

JVM運行原理是怎么樣的呢

代碼測試:


   
   
  

  1.     public static void main(String[] args){

  2.          long maxMemory = Runtime.getRuntime().maxMemory();

  3.          Long totalMemory = Runtime. getRuntime().totalMemory();

  4.          System.out.println("MAX_MEMORY ="+maxMemory +"(字節)、"+(maxMemory/(double)1024/1024) + "MB");

  5.          System.out.println("TOTAL_ MEMORY = "+totalMemory +"(字節)"+(totalMemory/(double)1024/1024) + "MB");



說明:在Run as ->Run Configurations中輸入"-XX:+PrintGCDetails"可以查看堆內存運行原理圖:

(1) 在jdk1.7中:

JVM運行原理是怎么樣的呢

 (2) 在jdk1.8中:

JVM運行原理是怎么樣的呢

6.通過參數設置自動觸發垃圾回收:

public class JVMTest {

     public static void main(String[] args){

          long maxMemory = Runtime.getRuntime().maxMemory();//返回Java虛擬機試圖使用的最大內存量。

          Long totalMemory = Runtime. getRuntime().totalMemory();//返回Java虛擬機中的內存總量。

          System.out.println("MAX_MEMORY ="+maxMemory +"(字節)、"+(maxMemory/(double)1024/1024) + "MB");

          System.out.println("TOTAL_ MEMORY = "+totalMemory +"(字節)"+(totalMemory/(double)1024/1024) + "MB");

          while(true){

          }

     }

}

 在Run as ->Run Configurations中輸入設置“-Xmx8m –Xms8m –xx:+PrintGCDetails”可以參看垃圾回收機制原理:

JVM運行原理是怎么樣的呢看完上述內容,你們掌握JVM運行原理是怎么樣的呢的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

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

jvm
AI

临朐县| 韶山市| 长岭县| 车险| 伊宁县| 盐山县| 崇明县| 星子县| 土默特左旗| 建水县| 广汉市| 浙江省| 布尔津县| 万盛区| 扶余县| 皮山县| 抚顺县| 长寿区| 合作市| 洞头县| 古田县| 盐源县| 兰州市| 偏关县| 池州市| 南安市| 舒城县| 顺平县| 桦川县| 杭锦旗| 阿瓦提县| 泽普县| 巴南区| 襄城县| 武宁县| 肥东县| 图木舒克市| 彩票| 武隆县| 响水县| 武定县|