• <center id="q6uyy"><td id="q6uyy"></td></center>
    <dd id="q6uyy"></dd>
  • 推廣 熱搜: csgo  vue  angelababy  2023  gps  新車  htc  落地  app  p2p 

    Java 程序是如何運行的呢?

       2023-08-07 網絡整理佚名2370
    核心提示:程序是如何運行的呢?棧中又會包含多個棧幀,每運行一個方法就創建一個棧幀,用于存儲局部變量表、操作棧、方法返回值等。直接內存并不是虛擬機運行時數據區的一部分。程序員提供了訪問方法區內的數據結構的接口。文件的字節流中包含的信息符合當前虛擬機的要求,并且不會危害虛擬機自身的安全。參數來關閉大部分的類驗證措施,以縮短虛擬機類加載的時間。對類的靜態變量,靜態代碼塊執行初始化操作

    Java程序是如何運行的?

    我們編寫的是.java文件,需要通過javac編譯生成.class文件,這樣class文件才能被JVM識別。 我們經??吹降?jar文件實際上是.class文件的壓縮包(減少文件數量,方便操作),加載到JVM后才能運行。

    來自網絡

    從上面可以看出,JVM由以下幾個部分組成

    1. 類加載、執行引擎、運行數據區以及垃圾回收器

    。

    運行數據區

    圖片.png

    運行時數據區主要可以分為5個區域

    1 方法區(Area)

    方法區由兩部分組成

    1. 永久代(Permanent Generation

    存放類結構信息的地方,包括常量池、靜態變量、構造函數、運行時常量池(Pool)等,以及編譯后的代碼(JIT)的代碼緩存。 雖然JVM規范將方法區描述為堆的邏輯部分,但它有一個別名non-heap(非堆),所以不要混淆它。

    (永久代) - -XX:設置上限,-XX:設置最小值示例:VM Args:-XX:=10M -XX:=10M。 如果空間不足,就會引發 java.lang.: space 異常。

    從JAVA8開始,持久代被完全刪除,并被另一個內存區域(也稱為元空間)取代。 它是本地堆內存的一部分。 可以通過-XX:和-XX:來調整。 當達到XX:指定的閾值時,就會開始清理該區域。 如果本地空間中的內存耗盡,則會收到 java .lang.: for space 的錯誤消息。

    代碼緩存 - 該緩存區域用于存儲編譯后的代碼。 編譯后的代碼是本機代碼(與硬件相關),由JIT(Just In Time)編譯器生成,這是JVM特有的。

    2 java堆(Heap)

    java實例或對象存儲的地方。 這是GC的主要區域。 堆的大小可以通過 JVM 選項 -Xms 和 -Xmx 進行調整。 當堆耗盡時,JVM會拋出java.lang。 例外。 從存儲的內容我們很容易知道方法區和堆是所有java線程共享的。

    堆分為:

    3 java棧(Stack)

    java 堆棧始終與線程相關聯。 每當創建一個線程時,JVM就會為該線程創建一個對應的java棧。 在這個java堆棧中,將包含多個堆棧幀。 每次運行方法時,都會創建一個堆棧幀來存儲局部變量表、操作堆棧和方法返回值。 每個方法從調用到執行完成的過程對應著一個棧幀被壓入java棧到出棧的過程。 所以java棧是線程私有的。

    4 程序計數器(PC)

    用于保存當前線程執行的內存地址。 由于JVM程序是由多個線程執行的(線程輪流切換),為了保證線程切換回來后能夠恢復到原來的狀態,需要有一個獨立的計數器來記錄之前被中斷的地方。 可見程序計數器也是線程私有的。

    5 原生方法棧(Stack)

    它與java棧的功能類似,但它服務于JVM使用的方法。 原生方法棧的參數順序和返回值與典型的C程序相同。

    6 原生方法接口

    主要調用C或C++實現的本地方法并返回結果。

    7 直接存儲器

    直接內存不是虛擬機運行時數據區域的一部分。

    在NIO中,引入了一種基于通道和緩沖區的I/O方法,可以使用函數直接分配堆外內存,然后通過java堆中存儲的一個對象作為對這塊內存的引用進行操作。 -XX:設置最大值,默認與java堆的最大值相同。

    類加載

    JVM將類加載分為3步:

    鏈接(link)分為3步,如下圖:

    圖片.png

    負載(負載)

    查找并加載類二進制數據(查找并導入Class文件)

    加載是類加載過程的第一個階段。 在加載階段,虛擬機需要完成以下三件事:

    1) 通過類的全限定名獲取類定義的二進制字節流。

    2)將此字節流表示的靜態存儲結構轉換為方法區的運行時數據結構。

    3)在Java堆中生成一個代表該類的java.lang.Class對象,作為方法區數據的訪問入口。

    與類加載的其他階段相比,加載階段(準確地說是加載階段獲取類的二進制字節流的動作)是最可控的階段,因為開發者可以使用系統提供的類加載器來完成加載,也可以自定義自己的類加載器來完成加載。

    加載階段完成后,虛擬機外部的二進制字節流按照虛擬機要求的格式存儲在方法區中,同時在Java堆中也創建了一個類java.lang.Class的對象,所以Java 程序員可以提供訪問方法區中數據結構的接口。

    那么class文件加載的原理是什么呢? 需要滿足雙親委派原則,通過類加載器來加載。 類加載器分為以下幾種類型:

    [圖片上傳失敗...(image--22)]

    在加載過程中,會首先檢查類是否已經加載。 檢查的順序是從下到上、從上到下逐層檢查。 只要加載了某個類,就認為已加載,并且保證所有此類類都被加載一次。 加載的順序是自上而下的,即上層嘗試逐層加載該類。

    鏈接(分3步) 1)驗證:確保加載的類的正確性

    驗證是連接階段的第一步。 該階段的目的是保證Class文件字節流中包含的信息滿足當前虛擬機的要求,不會危及虛擬機本身的安全。 在驗證階段,大致會完成四個階段的檢查動作:

    文件格式驗證:驗證字節流是否符合Class文件格式的規范; 例如:是否以 開頭,主次版本號是否在當前虛擬機的處理范圍內,常量池中的常量是否有不支持的類型。

    元數據驗證:對字節碼描述的信息進行語義分析(注:對比javac編譯階段的語義分析),確保其描述的信息符合Java語言規范的要求; 例如:這個類是否在.lang之外有除java之外的父類。

    字節碼驗證:通過數據流和控制流分析,確定程序語義合法、邏輯正確。

    符號引用驗證:確保解析動作能夠正確執行。

    驗證階段非常重要,但不是必需的。 它對程序運行時間沒有影響。 如果引用的類已經被反復驗證,可以考慮使用--參數關閉大部分類驗證措施,以縮短虛擬機類加載時間。 時間。

    2)準備工作:為類的靜態變量分配內存并初始化為默認值

    準備階段是正式為類變量分配內存并設置類變量初始值的階段,這些內存將在方法區中分配。 此階段需要記住以下幾點:

    假設一個類變量定義為:int value = 3; 那么準備階段之后變量值的初始值為0,而不是3,因為還沒有執行過任何Java方法,而給3賦值的指令是在程序編譯后存儲在類構造函數中的()方法,所以給3賦值的動作會在初始化階段執行。

    3)解析:將類中的符號引用轉換為直接引用

    解析階段是虛擬機用直接引用替換常量池中的符號引用的過程。 解析動作主要針對7類符號引用:類或接口、字段、類方法、接口方法、方法類型、方法句柄、調用限定符。 符號引用是描述目標的一組符號,可以是任何文字。

    直接引用是直接指向目標的指針、相對偏移量或間接定位目標的句柄。

    初始化

    對類的靜態變量和靜態代碼塊進行初始化操作

    初始化為類的靜態變量賦予正確的初始值,JVM負責類的初始化,主要針對類變量。 Java中初始化類變量有兩種方法:

     
    標簽: jvm 虛擬機 線程
    反對 0舉報 0 收藏 0 打賞 0評論 0
     
    更多>同類資訊
    推薦圖文
    推薦資訊
    點擊排行
    網站首頁  |  關于我們  |  聯系方式  |  使用協議  |  版權隱私  |  網站地圖  |  排名推廣  |  廣告服務  |  積分換禮  |  網站留言  |  RSS訂閱  |  違規舉報
    Powered By DESTOON
     
    三级精品影视国产,欧美乱伦免费综合,亚洲a在线中文,人妻色综合网站
  • <center id="q6uyy"><td id="q6uyy"></td></center>
    <dd id="q6uyy"></dd>