JVM原理機制筆記

1.JVM 簡介

JVM 全稱是Java Virtual Machine Java 虛擬機,也就是在計算機上再虛擬一個計算機。java

這和咱們使用 VMWare 不同,那個虛擬的東西你是能夠看到的,這個JVM 你是看不到的,它存在內存中程序員

計算機的基本構成是:運算器控制器存儲器輸入輸出設備編程

JVM 也是有這成套的元素:框架

    運算器 -固然是交給硬件CPU 還處理jvm

      爲了適應一次編譯,隨處運行的狀況,須要作一個翻譯動做,因而就用了JVM 本身的命令集。編程語言

   這與彙編的命令集有點相似,每一種彙編命令集針對一個系列的CPU 函數

好比8086 系列的彙編也是能夠用在8088 上的,可是就不能跑在8051 上。url

   JVM 的命令集則是能夠處處運行的,由於JVM根據不一樣的CPU ,翻譯成不一樣的機器語言。spa

   存儲器 - JVM 是一個內存中的虛擬機,那它的存儲器就是內存了。操作系統

                     咱們寫的全部類、常量、變量、方法都在內存中

 

2.JVM的組成部分

JVM 是運行在操做系統之上的,它與硬件沒有直接的交互

                    

 

JVM 構成圖,整個JVM 分爲四部分

     

                    

1)      Class Loader 類加載

類加載器的做用是加載類文件到內存,

好比編寫一個HelloWord.java 程序,而後經過javac 編譯成class 文件,

那怎麼才能加載到內存中被執行呢?Class Loader 承擔的就是這個責任。

Class Loader 只管加載,只要符合文件結構就加載,

至於說能不能運行,則不是它負責的,那是由Execution Engine 負責的。

2)      Execution Engine 執行引擎

也叫作解釋器(Interpreter) ,負責解釋命令,提交操做系統執行。

3)      Native Interface 本地接口

本地接口的做用是融合不一樣的編程語言爲Java 所用,它的初衷是融合C/C++

目前該方法使用已經比較少見了,由於如今的異構領域間的通訊很發達,

好比可使用Socket 通訊,也可使用Web Service

4)      Runtime data area 運行數據區

運行數據區是整個JVM 的重點。咱們全部寫的程序都被加載到這裏,以後纔開始運

                整個JVM 框架由加載器加載文件,而後執行器在內存中處理數據,須要與異構系統交互是能夠經過本地接口進行,一個完整的系統誕生了。

 

 

3.JVM加載class文件的原理機制

1. Java中的全部類,必須被裝載到jvm中才能運行。

這個裝載工做是由jvm中的類裝載器完成的,類裝載器所作的工做實質是把類文件從硬盤讀取到內存中。

 

2. Java中的類大體分爲三種

  1) 系統

  2) 擴展類

    3) 由程序員自定義的

 

3. 類裝載方式,有兩種:

     1) 隱式裝載。 程序在運行過程當中當碰到經過new 等方式生成對象時,

    隱式調用類裝載器加載對應的類到jvm中。

  2) 顯式裝載。 經過class.forname()等方法,顯式加載須要的類。

隱式加載與顯式加載的區別:

 

4.類加載的動態性體現:

     一個應用程序老是由n多個類組成,Java程序啓動時,並非一次把全部的類所有加載後再 .

  它老是先把保證程序運行的基礎類一次性加載到jvm中,其它類等到jvm用到的時候再加.

  這樣的好處是節省了內存的開.

 

5. Java類裝載:

   Java中的類裝載器實質上也是類,功能是把類載入jvm.

      值得注意的是jvm的類裝載器並非一個,而是三個。

   爲何要有三個類加載器,一方面是分工,各自負責各自的區塊,另外一方面爲了實現委託模

      Bootstrap Loader                                   - 負責加載系統類(C++語言寫)            搜索路徑:sun.boot.class.path

                                |

                                ExtClassLoader                  - 負責加載擴展類                                        搜索路徑:java.ext.dirs

                                                |

                                                AppClassLoader  - 負責加載應用類                                       搜索路徑:java.class.path

 

6. 類加載器之間是如何協調工做:

   在這裏java採用了委託模型機.

   類裝載器有載入類的需求時,會先請示其Parent使用其搜索路徑幫忙載入,

若是Parent 找不到,那麼才由本身依照本身的搜索路徑搜索類。

 

7. 預先加載(pre-loading)依需求加載(load-on-demand):

     1) JRE 運行的開始會將 Java 運行所須要的基本類採用預先加載 pre-loading )的方法所有加載要內存.

      主要包括 JRE rt.jar 文件裏面全部的 .class

  2) java.exe 虛擬機開始運行之後,它會找到安裝在機器上的 JRE 環境,而後把控制權交給 JRE .

 JRE 的類加載器會將 lib 目錄下的 rt.jar 基礎類別文件庫加載進內.

     3) 相對於預先加載,咱們在程序中須要使用本身定義的類的時候就要使用依需求加載方法

load-on-demand ),就是在 Java 程序須要用到的時候再加載,以減小內存的消.


8.自定義類加載機制:

  通常咱們都是調用系統的 類加載器來實現加載的,其實咱們是能夠本身定義類加載器的

  利用 Java 提供的 java.net.URLClassLoader 類就能夠實現。

      try {  

URL url = new  URL( "file:/d:/test/lib/" );  

URLClassLoader urlCL = new  URLClassLoader( new  URL[]{url});  

Class c = urlCL.loadClass("TestClassA" );  

TestClassA object = (TestClassA)c.newInstance();  

object.method();  

}catch (Exception e){  

e.printStackTrace();  

}

 

9.類加載器的階層體系:

  1)Java 類加載器工做原:

      當執行 java ***.class 的時候, java.exe 會幫助咱們找到 JRE

                接着找到位於 JRE 內部的 jvm.dll ,這纔是真正的 Java 虛擬機

      最後加載動態庫,激活 Java 虛擬機

 

      虛擬機器激活之後,會先作一些初始化的動做,好比說讀取系統參數等

      一旦初始化動做完成以後,就會產生第一個類加載器―― Bootstrap Loader

           Bootstrap Loader 是由 C++ 所撰寫而

      Bootstrap Loader 所作的初始工做中,除了一些基本的初始化動做以外,

最重要的就是加載 Launcher.java 之中的 ExtClassLoader ,並設定其 Parent null

表明其父加載器爲 BootstrapLoader

                    而後 Bootstrap Loader 再要求加載 Launcher.java 之中的 AppClassLoader

並設定其 Parent 爲以前產生的 ExtClassLoader

      *Launcher$ExtClassLoader.class Launcher$AppClassLoader.class 都是由 Bootstrap Loader 所加載

因此 Parent 和由哪一個類加載器加載沒有關係

 

2)類加載器之間的關係

BootstrapLoader <---(Extends)----AppClassLoader <---(Extends)----ExtClassLoader

這三個加載器就構成咱們的 Java 類加載體

 

  3) 他們分別從如下的路徑尋找程序所須要的類

BootstrapLoader sun.boot.class.path
ExtClassLoader:         java.ext.dirs
AppClassLoader:       java.class.path

這三個系統參量能夠經過 System.getProperty() 函數獲得具體對應的路徑

相關文章
相關標籤/搜索