JAVA概述

1. Java技術與Java虛擬機

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

運行期環境表明着Java平臺,開發人員編寫Java代碼(.java文件),而後將之編譯成字節碼(.class文件)。最後字節碼被裝入內存,一旦字節碼進入虛擬機,它就會被解釋器解釋執行,或者是被即時代碼發生器有選擇的轉換成機器碼執行。從上圖也能夠看出Java平臺由Java虛擬機和 Java應用程序接口搭建,Java語言則是進入這個平臺的通道,用Java語言編寫並編譯的程序能夠運行在這個平臺上。這個平臺的結構以下圖所示: 程序員

Java平臺的結構中, 能夠看出,Java虛擬機(JVM) 處在覈心的位置,是程序與底層操做系統和硬件無關的關鍵。它的下方是移植接口,移植接口由兩部分組成:適配器和Java操做系統, 其中依賴於平臺的部分稱爲適配器;JVM 經過移植接口在具體的平臺和操做系統上實現;在JVM 的上方是Java的基本類庫和擴展類庫以及它們的API 利用Java API編寫的應用程序 (application) 和小程序 (Java applet) 能夠在任何Java平臺上運行而無需考慮底層平臺, 就是由於有Java虛擬機 (JVM) 實現了程序與操做系統的分離,從而實現了Java 的平臺無關性。 編程

那麼到底什麼是Java虛擬機(JVM)呢?一般咱們談論JVM時,咱們的意思多是: 小程序

1.       JVM規範的比較抽象的說明; 數組

2.       JVM的具體實現; app

3.       在程序運行期間所生成的一個JVM實例。 編程語言

JVM規範的抽象說明是一些概念的集合,它們已經在書《The Java Virtual Machine Specification》(《Java虛擬機規範》)中被詳細地描述了;對JVM的具體實現要麼是軟件,要麼是軟件和硬件的組合,它已經被許多生產廠商所實現,並存在於多種平臺之上;運行Java程序的任務由JVM的運行期實例單個承擔。在本文中咱們所討論的Java虛擬機(JVM)主要針對第三種狀況而言。它能夠被當作一個想象中的機器,在實際的計算機上經過軟件模擬來實現,有本身想象中的硬件,如處理器、堆棧、寄存器等,還有本身相應的指令系統。 函數

JVM在它的生存週期中有一個明確的任務,那就是運行Java程序,所以當Java程序啓動的時候,就產生JVM的一個實例;當程序運行結束的時候,該實例也跟着消失了。下面咱們從JVM的體系結構和它的運行過程這兩個方面來對它進行比較深刻的研究。 spa

2. Java虛擬機的體系結構

剛纔已經提到,JVM能夠由不一樣的廠商來實現。因爲廠商的不一樣必然致使JVM在實現上的一些不一樣,然而JVM仍是能夠實現跨平臺的特性,這就要歸功於設計JVM時的體系結構了。 操作系統

咱們知道,一個JVM實例的行爲不光是它本身的事,還涉及到它的子系統、存儲區域、數據類型和指令這些部分,它們描述了JVM的一個抽象的內部體系結構,其目的不光規定實現JVM時它內部的體系結構,更重要的是提供了一種方式,用於嚴格定義實現時的外部行爲。在JVM specification對JVM內存的描述中,其主要包括 兩個子系統——Class loader (類裝載器),Execution engine(執行引擎)和 兩個組件——Runtime data area (運行時數據區域),Native interface(本地接口),這幾個組成的體系結構圖爲:

Class loader:根據給定的全限定名類名 (如 java.lang.Object) 來裝載class文件的內容到 Runtime data area中的method area (方法區域) 。Java程序員能夠extends java.lang.ClassLoader類來寫本身的Class loader

Execution engine執行classes中的指令。任何JVM specification實現 (JDK) 的核心是Execution engine, 換句話說:Sun 的JDK 和IBM的JDK好壞主要取決於他們各自實現的Execution engine的好壞。每一個運行中的線程都有一個Execution engine的實例

 Native interfacenative libraries 交互,是其它編程語言交互的接口

          Runtime data area 組件:這個組件就是JVM中的內存。

詳細說明見深刻理解JVM內存模型

3. Java虛擬機的運行過程

虛擬機經過調用某個指定類的方法main啓動,傳遞給main一個字符串數組參數,使指定的類被裝載,同時連接該類所使用的其它的類型,而且初始化它們。例如對於程序:

class HelloApp
{
   public static void main(String[] args)
   {
       System.out.println("Hello World!");
       for (int i = 0; i < args.length; i++ )
       {
          System.out.println(args[i]);
       }
   }
}

編譯後在命令行模式下鍵入: java HelloApp run virtual machine

將經過調用HelloApp的方法main來啓動java虛擬機,傳遞給main一個包含三個字符串"run""virtual""machine"的數組。如今咱們略述虛擬機在執行HelloApp時可能採起的步驟。

開始試圖執行類HelloAppmain方法,發現該類並無被裝載,也就是說虛擬機當前不包含該類的二進制表明,因而虛擬機使用 ClassLoader試圖尋找這樣的二進制表明。若是這個進程失敗,則拋出一個異常。類被裝載後同時在main方法被調用以前,必須對類 HelloApp與其它類型進行連接而後初始化。連接包含三個階段:檢驗,準備和解析。檢驗檢查被裝載的主類的符號和語義,準備則建立類或接口的靜態域以及把這些域初始化爲標準的默認值,解析負責檢查主類對其它類或接口的符號引用,在這一步它是可選的。類的初始化是對類中聲明的靜態初始化函數和靜態域的初始化構造方法的執行。一個類在初始化以前它的父類必須被初始化。整個過程以下:

相關文章
相關標籤/搜索