JVM入門(一)類的加載過程

2020-09-05 Java程式設計師技術分享

在講JVM最開始,我們先以一個簡單的Java程序的運行開始講,JAVA程序的運行原理。下面我先把我們實例程序列出來,我們該實例程序一共有兩個java文件:Hello.java和Person.java:

Hello.java文件:

public class Hello { public static void main(String[] args) { Person p = new Person(); }}

Person.java文件

public class Person { private String name;}

首先在IDE中編寫java源文件,文件名以.java結束。編寫完源文件,然後使用javac命令把源文件編譯成以.class結尾的二進位文件或者打包為jar文件。

當我們需要去執行我們編寫的java程序的時候,如果是直接編譯後的.class文件,那麼使用:

java com.xx.Hello.class

java *.class命令去運行包含了main方法的那個.class文件。如果我們是以jar的方式進行運行java程序,那麼執行 :

java -jar *.jar com.xx.Hello

起中 Hello是這個jar中包含了main方法的類的名稱。

無論是那種方式,當我們執行的時候,就會啟動jvm虛擬機去加載所要執行的Hello.class文件到虛擬機中。然後在jvm中有字節碼執行引擎負責去執行Hello.class中的main方法,在main方法中使用到了Person類,此時jvm又會去加載Person。也就是說jvm用到哪個類,然後就去加載哪個類。下面用圖來描述一下java程序的執行過程:

java執行過程

1.執行java命令啟動jvm,通過類加載器Hello.class加載到jvm中

2.jvm中的字節碼執行引擎執行Hello.class中入口方法main方法

3.由於main使用了Person類,然後jvm類加載器再去加載Person類。

4.最後字節碼執行引擎執行Person.class。

類的加載過程

通過上面的結束,基本了解了java程序的一個大致的執行過程,在上面描述的加載過程中,其中一個最重要的環節是類的加載。下面接受一下類是如何加載的。

在Java類被加載到虛擬機到從內存中卸載,整個生命周期包括以下部分:

加載,連接,初始化,使用,卸載

在java中的所有的類型都是在運行的過程中進行加載,連接和初始化。

類的加載過程分為三個部分:

加載:把class文件加載到內存中

連接:分為三個部分:驗證,準備,解析。

初始化:類加載最後一步,對類中的變量進行賦值,在代碼層面是就是執行用戶在類中的定義的賦值語句。

連接

其中連接又分為三個部分:

驗證: 主要是包括文件格式驗證,元數據驗證,字節碼驗證

準備: 準備階段是為類分配內存空間。

解析: 將虛擬機常量池內的符合引用替換為直接引用的過程,這部分比較複雜以後會詳細說。

#初始化

類的初始化虛擬機規範規定:只有在5種情況下才會發生:

1.執行new 對象操作、讀取活設置一個類的靜態欄位(不包括用final修飾過的,因為final修飾的屬性已經在編譯器被放到常量池中)、調用一個類的靜態方法。

2.使用reflect包的方法對類進行反射調用的時候。

3.當初始化一個類的時候,如果父類沒有初始化,先完成對父類的初始化。

4.當JVM啟動的時候,需要指定一個執行main方法的主類,那麼虛擬機會首先初始化這個主類。

5.JDK 7 中使用動態語言支持時,如果一個 java.lang.invoke.MethodHandle 實例正好是對 REF_getStatic, REF_putStatic, REF_invokeStatic 進行方法句柄解析的結果時。

>1.對於接口的初始化,對於子接口與父接口的規則與java類不一樣,子接口的初始化並不要求父接口全部都完成了初始化,只有在真正使用到父接口的時候,才會對父接口進行初始化。

2.如果接口中定義了默認實現方法,那麼當實現這個接口的類初始化的時候,也會除非這個接口的初始化。

以上五點被稱為主動使用,只有主動使用的時候,類才會被初始化。而被動使用是不會引起類的初始化的。類的被動使用又主要包括下面三種情況:

* 通過子類引用父類的靜態屬性,父類初始化,但是子類不會被初始化

* 定義某個類的數組,該類不會初始化

* 使用類修飾的final的屬性,也不會引起類初始化。

相關焦點

  • 大白話談JVM的class類加載機制
    JAVA代碼的運行流程首先我們就來聊一聊JAVA代碼是怎麼運行起來的,這部分比較基礎相信大家都知道,就當成是個複習吧。我們編寫的代碼都是在java文件中編寫的,然後會編譯成class字節碼文件。當我們使用到哪個類的時候就會通過類加載器把class字節碼文件中的類加載到jvm內存中,然後就是在jvm內存中運行我們的代碼了。
  • 深入淺出JVM性能調優——JVM內存模型和類加載運行機制
    :jvm 使用類加載器來加載一個類,這個類加載器是和這個類型綁定的,因此會在類型信息中存儲這個類加載器的引用6)指向 Class 類的引用:每 一個被加載的類型,jvm 都會在堆中創建一個 java.lang.Class 的實例,類型信息中會存儲 Class 實例的引用
  • 十個問題弄清JVM&GC(一)
    以及它的主要作用JVM的核心功能有哪些類加載機制和過程運行時數據區的邏輯結構JVM的內存模型如何確定對象是垃圾垃圾收集的算法有哪些各種問世的垃圾收集器JVM調優的參數配置一、JVM、JRE和JDK的區別和聯繫
  • JVM中Java類的生命周期,一文搞定
    目錄:類生命周期加載(Loading)四種類加載器 JAVA_HOME 目錄裡面的內容雙親委任連接(Linking)驗證階段準備階段解析階段初始化類初始化的七種觸發情況卸載>JVM每本Java入門書籍在介紹Java這門語言的時候都會提到Java跨平臺,「一次解釋,到處運行的特點「,功臣就是jvm(Java Virtual Machine,Java虛擬機)。
  • 深入解析JVM類加載器子系統,你還不了解的都在這裡
    Resolve(解析)   (1)將常量池內的符號引用轉換為直接引用的過程。   (2)事實上,解析操作往往會伴隨著jvm在執行完初始化之後再執行。3.Initialization(初始化)環節初始化階段就是執行類構造器方法clinit()的過程。此方法不需要定義,是javac編譯器自動收集類中的所有類變量的賦值動作和靜態代碼塊中的語句合併而來。
  • JVM類加載過程——下
    類與類加載器 比較兩個類是否「相等」,只有在這兩個類是由同一個類加載器加載的前提下才有意義,否則,即使這兩個類來源於同一個Class文件,被同一個虛擬機加載,只要加載它們的類加載器不同,那這兩個類就必定不相等。
  • JVM類加載過程——上
    ,類的加載過程必須按照這種順序按部就班地開始,而解析階段則不一定。加載 在加載階段,虛擬機需要完成以下3個事情: 1)、通過一個類的全限定名來獲取定義此類的二進位字節流 2)、將這個字節流所代表的靜態存儲結構轉化為方法區的運行時數據結構 3)、在內存中生成一個代表這個類的java.lang.Class對象,作為方法區這個類的各種數據的訪問入口
  • 一文徹底搞懂|JVM 類加載機制
    學習導圖一.為什麼要學習類加載機制?今天想跟大家嘮嗑嘮嗑Java的類加載機制,這是Java的一個很重要的創新點,曾經也是Java流行的重要原因之一。檢驗過程包括下面四個階段:A.文件格式驗證:B.元數據驗證:C.字節碼驗證:D.符號引用驗證:內容:對類自身以外(如常量池中的各種符號引用)的信息進行匹配性校驗
  • 關於JVM類加載機制,看這一篇就夠了
    不過這裡類加載器之間的父子關係一般不是以繼承(Inheritance)的關係來實現的,而是通常使用組合(Composition)關係來復用父加載器的代碼。(按照文件名識別,如rt.jar、tools.jar,名字不符合的類庫即使放在lib目錄中也不會被加載)類庫加載到虛擬機內存中。
  • JVM性能調優——JVM內存模型和類加載運行機制
    異常表5)指向類加載器的引用:jvm 使用類加載器來加載一個類,這個類加載器是和這個類型綁定的,因此會在類型信息中存儲這個類加載器的引用6)指向 Classjava 源文件編譯成 class 文件後,jvm 通過類加載器把 class 文件加載到虛擬機,然後經過類連接(類連接又包括驗證、準備、解析三個階段),最後經過初始化,字節碼就可以被解釋執行了。對於一些熱點代碼,虛擬機還存在一道即時編譯,會把字節碼編譯成本地平臺相關的機器碼,以提高熱點代碼的執行效率。
  • 詳解JVM類加載
    如果沒有,就必須執行相應的類加載過程。1.2 分配內存在類加載檢查通過後,虛擬機將為新生對象分配內存。指針碰撞:適用於堆內存規整(沒有內存碎片)的情形。原理:用過的內存整理到一邊,未使用的內存放在另一邊,中間有一個分界值指針,只需要向著未使用過的內存方向將該指針移動對象內存大小位置即可。採用的GC收集器有Serial和ParNew(因為使用標記-整理,不存在內存碎片)。空閒列表:適用於堆內存不規整的情形。
  • JVM的藝術—類加載器篇
    Person的時候,根據雙親委託模型,我們的Person並沒有被自定義類加載(Test01ClassLoader)加載,而是被AppClassloader加載成功,同時根據全盤委託規則,我們的Dog類也被AppClassLoader加載了。
  • 20張圖解密JVM類加載子系統,瞬間豁然開朗
    在.class文件 ---> JVM ---> 最終成為元數據模板,此過程就要一個運輸工具(類裝載器 Class Loader),扮演一個快遞員的角色。,或從JDK的安裝目錄的jre/lib/ext子目錄(擴展目錄)下加載類庫。
  • 大廠面試系列(一)::JVM基礎
    類加載器的本質類加載器為什麼有三層結構怎麼自定義類加載器做容器隔離?講講類加載機制唄?都有哪些類加載器,這些類加載器都加載哪些文件?手寫一下類加載Demo Classloader作用講一講類加載器工作機制?你知道強引用、弱引用和軟引用嗎?為什麼要有這些東西?他們有什麼作用?
  • JVM加載class文件的原理機制詳解
    類裝載方式,有兩種   1.隱式裝載, 程序在運行過程中當碰到通過new 等方式生成對象時,隱式調用類裝載器加載對應的類到jvm中,   2.顯式裝載, 通過class.forname()等方法,顯式加載需要的類   隱式加載與顯式加載的區別:兩者本質是一樣?
  • 一文教你讀懂JVM的類加載機制
    今天,我們的主角就是類加載機制 - 說白了,就是將.class文件加載到JVM內存中,並將其轉化為java.lang.Class對象的過程。這對這個過程,我們可以細分為如下幾個階段:加載連接(驗證,準備,解析)初始化
  • jvm - 深入理解Java類加載
    (一)加載通過全限定類名來獲取定義此類的二進位字節流。將這個字節流所代表的靜態存儲結構轉化為方法區的運行時數據結構。在內存中生成一個代表這個類的 java.lang.Class 對象,作為方法區這個類的各種數據的訪問入口。
  • java類加載機制和類加載器
    程序在啟動的時候,並不會一次性加載程序所要用到的所有class文件,而是根據需要,通過java的類加載器機制(classLoader)來動態加載某個class文件到內存中。jvm在運行時會產生三個classLoader:啟動類加載器(BootStrap ClassLoader):是java類加載層次中最頂層的類加載器,負責加載jdk中的核心類庫。
  • 騷操作:不重啟 JVM,如何替換掉已經加載的類?
    【019期】JavaWeb面試題(一):JDBC【021期】JavaWeb面試題(二):HTTP協議【022期】JavaWeb面試題(三):Cookie和Session【023期】JavaWeb面試題(四):JSP【024期】JavaWeb面試題(五):Filter和Listener【025期】Java工具面試題(一):版本控制工具
  • jvm系列一:我們的java程序如何跑起來
    2、jvm如何加載class字節碼上文提到將class字節碼加載到jvm內存中,其實就是一個類加載過程。那麼我們的類加載過程是怎麼樣的呢?,類是什麼時候加載到內存的,它的入口是什麼?當然,當我們啟動一個jvm進程時,類就會加載到內存中,並且在類中找到main方法,這個就是入口,從而開始加載你的程序,以下面這個程序為例: