JAVA的執行

來源:互聯網
上載者:User

標籤:類型   解釋   地方   java技術   setname   解析   本地   class類   交流   

Java的運行原理

在Java中引入了虛擬機器的概念,即在機器和編譯器之間加入了一層抽象的虛擬機器。這台虛擬機器在任何平台上都提供給編譯器一個的共同的介面。編譯器只需要面向虛擬機器,產生虛擬機器能夠理解的代碼,然後由解譯器來將虛擬機器代碼轉換為特定系統的機器碼執行。在Java中,這種供虛擬機器理解的代碼叫做位元組碼(ByteCode)(class檔案的內容),它不面向任何特定的處理器,只面向虛擬機器。每一種平台的解譯器是不同的,但是實現的虛擬機器是相同的。Java來源程式經過編譯器編譯後變成位元組碼,位元組碼由虛擬機器解釋執行,虛擬機器將每一條要執行的位元組碼送給解譯器,解譯器將其翻譯成特定機器上的機器碼,然後在特定的機器上運行。

位元組碼:代碼通常是指一個程式或者程式的一部分,它對於人來說是可讀的。而位元組是儲存大小的單位,電腦可讀的資訊通常被組織為位元組。隨意術語位元組碼是對於電腦而言的可讀的程式。

JAVA是一種在設計時,同時借鑒了編譯型語言和解釋型語言的特性,被設計成為一種半編譯半解釋型的語言。也是一套完整的IT行業解決方案,包含了很多技術。從整體上劃分,JAVA技術可以分為Java程式設計語言和Java平台。

JAVA程式設計語言特性:簡單,物件導向,可移植,多線程,健壯和安全,動態,結構中立,高效能,分布式。

跨平台性:

話說,在北京,一般都是講北京話的,上海,一般都是將上海話,廣東,廣東話...
現有一公文發出,要全國執行,該當如何?——先統一翻譯成普通話。各地在將普通話版本翻譯成當地的方言。

這裡,北京、上海就是不同類型的機器windows,linux...
編譯(javac)就是將公文翻譯成普通話的過程,而編譯出的.class檔案,就是公文的普通話版本。
在執行的時候,各地的翻譯就是jvm,負責將.class轉換成本地能夠理解的方言來執行。

所謂平台是指程式啟動並執行硬體或者軟體環境。當今流行的平台有Linux,Windows,Unix,macOS等。Java平台跟這些平台最大的不同在於:java平台是一個運行在其他基於硬體的的平台之上的純軟體平台。Java平台有兩個組件:Java虛擬機器,JavaAPI。

Java虛擬機器(JVM)

Java虛擬機器(JVM)是Java Virtual Machine的縮寫,它是一個虛構出來的電腦,是通過在實際的電腦上模擬類比各種電腦功能類比來實現的。

Java中,類載入器把一個類裝入JAVA虛擬機器需要經過三個步驟來完成:裝載連結初始化,其中連結又分來校正、準備、解析過程

裝載:尋找和匯入.class檔案

連結:檢查裝入.class檔案的正確性,然後,java虛擬機器為變數分配記憶體,設定預設值

初始化:把符號引用變成直接引用。。。

 

現在假設這兩個java源檔案已經被編譯成了CLASS檔案了,我們來看看java虛擬機器怎麼執行的。

Java虛擬機器工作流程

1.裝載

描敘:Java虛擬機器裝載指定的CLASS檔案

結果:形成這個CLASS類的執行個體對象

過程:java虛擬機器使用類裝載器定位到相應的CLASS檔案,然後讀取這個CLASS檔案(一個線性位元據流),將它傳入java虛擬機器中。緊接著虛擬機器提取其中的類型資訊。比如:該類的類名,方法名,變數名,修飾符,方法的傳回型別等等。還有一個重要的東西就是常量池。(常量池儲存了該類型的所有常量,包括直接常量和對其他類型,欄位,方法的符號引用)將這些資訊儲存在一個叫做方法區的地方。最終形成CLASS類的執行個體,這個執行個體存放在記憶體的堆區。它成為了java程式與內部資料結構之間的介面,程式要訪問該類型的資訊,程式就調用該類型對應的CLASS執行個體對象的方法。簡而言之:這個過程就是把一個類型的位元據解析為方法區中的內部資料結構,並在堆上建立一個CLASS對象的過程。

樣本:裝載Main類

Java虛擬機器讀取Main類的CLASS檔案,生產對應的java.lang.Class類的執行個體,讀取其中的類型資訊,比如修飾符 private,public,static,另外變數 size,name,pwd,User(User即為一個引用)共同構成了這個類的常量池。將這些資訊儲存在方法區,

2.連結

描述:驗證,準備,解析(可選)

結果:這個類型是正確的。(這裡不知道該怎麼描述)

過程:

1)驗證:確定類型符合java語言的語義,比如:final類不能有子類,final方法不能被覆蓋,確保在類型和超類型之間沒有不相容的方法聲明(比如兩個方法擁有同樣的名字,參數完全相同,但傳回型別不同)。

2)準備:java虛擬機器為類變數分配記憶體,設定預設值

3)解析:在類型的常量池中尋找類,介面,欄位和方法的符合引用把這些符號引用替換成直接引用的過程。

樣本: 串連Main類

Java虛擬機器為size分配記憶體,並賦預設值0.找到常量池中User類的引用,如果User類還沒有被裝載,則裝載並且串連該類,然後將常量池中對User類的引用替換為直接引用。在此時User類並不會被初始化,因為還沒有用它。

3.初始化

描述:初始化一些靜態變數

結果:這個類型可以使用了

過程:可能會調用()方法,(這個方法只能夠由java虛擬機器調用)來初始化該類的靜態變數。在調用這個方法前,必須確認該類的超類的() 方法已經被調用。

樣本:初始化Main類

Java虛擬機器將Main類的靜態變數賦值為1.

4.使用(執行該類代碼了)

1.User u = new User();(存放在記憶體的堆區)

建立了一個User類執行個體,實際上是通過這個類的CLASS執行個體執行個體化的。方法如下:

User u=(User)Class.forName("User").newInstance();

為了方便,用C代替Class.forName("User")

2.u.setName("李文水"); u.setPwd("159");

調用該類的方法,為該類的變數賦值,Java虛擬機器內部調用是這樣的,通過方法區找到該方法,利用CLASS執行個體的如下方法調用:

c.getMethod("setName").invoke(u,"李文水");

3.String name = u.getName(); String pwd = u.getPwd();

與第二步類似,不同的是將取得的值分別賦給了變數name和pwd。關鍵是這個值儲存在哪裡?和執行個體對象一樣,存放在堆區。這個時候我應該可以看出CLASS執行個體的作用了,它就是起個中間作用,將程式中的調用反應到堆區上資料的變化。

4.u = null;


這個步驟寫出來的目的是瞭解一下Java虛擬機器記憶體回收機制。(沒有什麼實際意義)

Java虛擬機器內部會根據一種規則(這個對象是否可以觸及)來判斷這兩個類是否可以回收了?具體形式如下:

 

當執行 u = null;時這條線就被斬斷了,因此User執行個體就不可以觸及了,所以java虛擬機器就可以回收這個User執行個體了。

以上就是Java的運行,不足之處,歡迎交流。

 

JAVA的執行

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.