java虛擬機的基本原理,java虛擬機的基本原理有哪些

本文目錄一覽:

java虛擬機原理是什麼,如果要自己寫一個改怎麼入手

原理是先建一個進程,在實體機中運行,成為虛擬機,然後在此虛擬機上解釋、執行class代碼。代碼的編譯與運行都遵循了Jvm規範,建議你先閱讀「Java語言規範」「JVM原理」等相關書籍。

java虛擬機工作原理?

從宏觀上介紹一下Java虛擬機的工作原理。從最初編寫的Java源文件(.java文件)是如何一步步執行的,如下圖所示,首先Java源文件經過前端編譯器(javac或ECJ)將.java文件編譯為Java位元組碼文件,然後JRE加載Java位元組碼文件,載入系統分配給JVM的內存區,然後執行引擎解釋或編譯類文件,再由即時編譯器將位元組碼轉化為機器碼。主要介紹下圖中的類加載器和運行時數據區兩個部分。

(1)類加載指將類的位元組碼文件(.class)中的二進制數據讀入內存,將其放在運行時數據區的方法區內,然後在堆上創建java.lang.Class對象,封裝類在方法區內的數據結構。類加載的最終產品是位於堆中的類對象,類對象封裝了類在方法區內的數據結構,並且向JAVA程序提供了訪問方法區內數據結構的接口。如下是類加載器的層次關係圖。

啟動類加載器(BootstrapClassLoader):在JVM運行時被創建,負責加載存放在JDK安裝目錄下的jre\lib的類文件,或者被-Xbootclasspath參數指定的路徑中,並且能被虛擬機識別的類庫(如rt.jar,所有的java.*開頭的類均被Bootstrap ClassLoader加載)。啟動類無法被JAVA程序直接引用。

擴展類加載器(Extension ClassLoader):該類加載器負責加載JDK安裝目錄下的\jre\lib\ext的類,或者由java.ext.dirs系統變量指定路徑中的所有類庫,開發者也可以直接使用擴展類加載器。

應用程序類加載器(AppClassLoader):負責加載用戶類路徑(Classpath)所指定的類,開發者可以直接使用該類加載器,如果應用程序中沒有定義過自己的類加載器,該類加載器為默認的類加載器。

用戶自定義類加載器(User ClassLoader):JVM自帶的類加載器是從本地文件系統加載標準的java class文件,而自定義的類加載器可以做到在執行非置信代碼之前,自動驗證數字簽名,動態地創建符合用戶特定需要的定製化構建類,從特定的場所(數據庫、網絡中)取得java class。

注意如上的類加載器並不是通過繼承的方式實現的,而是通過組合的方式實現的。而JAVA虛擬機的加載模式是一種委派模式,如上圖中的1-7步所示。下層的加載器能夠看到上層加載器中的類,反之則不行。類加載器可以加載類但是不能卸載類。說了一大堆,還是感覺需要拿點代碼說事。

首先先定義自己的類加載器MyClassLoader,繼承自ClassLoader,並覆蓋了父類的findClass(String name)方法,如下:

利用定義的類加載器加載指定的位元組碼文件,如通過MyClassLoader加載C:\\Users\\Administrator\\下的Test.class位元組碼文件,代碼如下所示:

(2)運行時數據區

位元組碼的加載第一步,其後分別是認證、準備、解析、初始化,那麼這些步驟又具體做了哪些工作,如下圖所示:

(3)如下將介紹運行時數據區,主要分為方法區、Java堆、虛擬機棧、本地方法棧、程序計數器。其中方法區和Java堆一樣,是各個線程共享的內存區域,而虛擬機棧、本地方法棧、程序計數器是線程私有的內存區。

Java堆:Java堆是Java虛擬機所管理的內存中最大的一塊,被進程的所有線程共享,在虛擬機啟動時被創建。該區域的唯一目的就是存放對象實例,幾乎所有的對象實例都在這裡分配內存,隨着JIT編譯器的發展與逃逸分支技術逐漸成熟,棧上分配、標量替換等優化技術使得對象在堆上的分配內存變得不是那麼「絕對」。Java堆是垃圾收集器管理的主要區域。由於現在的收集器基本都採用分代收集算法,所以Java堆中還可以分為老年代和新生代(Eden、From Survivor、To Survivor)。根據Java虛擬機規範,Java堆可以處於物理上不連續的內存空間,只要邏輯上連續即可。該區域的大小可以通過-Xmx和-Xms參數來擴展,如果堆中沒有內存完成實例分配,並且堆也無法擴展,將會拋出OutOfMemoryError異常。

方法區:用於存儲被Java虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。不同於Java堆的是,Java虛擬機規範對方法區的限制非常寬鬆,可以選擇不實現垃圾收集。但並非數據進入了方法區就「永久」存在了,這區域內存回收目標主要是針對常量池的回收和對類型的卸載。如果該區域內存不足也會拋出OutOfMemoryError異常。

常量池:這個名詞可能大家也經常見,是方法區的一部分。Class文件除了有類的版本、字段、方法、接口等描述信息外,還有一項信息就是常量池,用於存放編譯期生成的各種字面量和符號引用。Java虛擬機運行期間,也可能將新的常量放入常量池(如String類的intern()方法)。

虛擬機棧:線程私有,生命周期與線程相同。虛擬機棧描述的是Java方法執行的內存模型:每個方法在執行時都會創建一個棧幀用於存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中入棧到出棧的過程。如果請求的站深度大於虛擬機所允許的深度,將拋出StackOverflowError異常,虛擬機棧在動態擴展時如果無法申請到足夠的內存,就會拋出OutOfMemoryError異常。

過最簡單的一段代碼解釋一下,程序在運行時數據區個部分的變化情況。

(4)通過編譯器將Test.java文件編譯為Test.class,利用javap -verbose Test.class對編譯後的位元組碼進行分析,如下圖所示:

(5)看看運行時數據區的變化:

什麼是 Java 虛擬機?

1.

java虛擬機定義: 虛擬機是一種抽象化的計算機,通過在實際的計算機上仿真模擬各種計算機功能來實現的。Java虛擬機有自己完善的硬體架構,如處理器、堆棧、寄存器等,還具有相應的指令系統。Java虛擬機屏蔽了與…

2.

java虛擬機的基本結構

原創文章,作者:YRSF,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/145412.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
YRSF的頭像YRSF
上一篇 2024-10-27 23:49
下一篇 2024-10-27 23:49

相關推薦

  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發佈。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Python 常用數據庫有哪些?

    在Python編程中,數據庫是不可或缺的一部分。隨着互聯網應用的不斷擴大,處理海量數據已成為一種趨勢。Python有許多成熟的數據庫管理系統,接下來我們將從多個方面介紹Python…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • Python通配符有哪些

    Python通配符是一種表示字符串中模糊匹配的有效工具,用於匹配與具有特定模式匹配的字符串。Python中主要的通配符有:*,?,[]和{}。 一、星號通配符 * 在Python中…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29

發表回復

登錄後才能評論