你寫的 Java 代碼是如何一步步輸出結果的?

你寫的 Java 代碼是如何一步步輸出結果的?

掃描下方二維碼 試讀

你寫的 Java 代碼是如何一步步輸出結果的?

目錄

一、編寫Java源程序

二、編譯Java源代碼

三、執行Java源文件

四、JVM如何執行字節碼文件

對于任何一門語言,要想達到精通的水平,研究它的執行原理(或者叫底層機制)不失為一種良好的方式。

在本篇文章中,將重點研究java源代碼的執行原理,即從程 序員編寫JAVA源代碼,到最終形成產品,在整個過程中,都經歷了什么?每一步又是怎么執行的?執行原理又是什么?

你寫的 Java 代碼是如何一步步輸出結果的?

一 編寫java源程序

java源文件: 指存儲java源碼的文件。

先來看看如下代碼:

你寫的 Java 代碼是如何一步步輸出結果的?

(1)java源文件名就是該源文件中public類的名稱

你寫的 Java 代碼是如何一步步輸出結果的?

(2)一個java源文件可以包含多個類,但只允許一個類為public

二 編譯java源代碼

當java源程序編碼結束后,就需要編譯器編譯。

安裝好jdk后,我們打開jdk目錄,有兩個.exe文件,即javac.exe(編譯源代碼,xxx.java文件) 和 java.exe(執行字節碼,xxx.class文件).

如下圖所示:

你寫的 Java 代碼是如何一步步輸出結果的?

1、切換到MyTest.java文件夾

你寫的 Java 代碼是如何一步步輸出結果的?

2、javac.exe編譯MyTest.java

你寫的 Java 代碼是如何一步步輸出結果的?

編譯后,發現e:/Blogs 目錄多了以class為后綴的文件:A.class,B.class和MyTest.class

你寫的 Java 代碼是如何一步步輸出結果的?

Tip :當javac.exe編譯java源代碼時,java源代碼有幾個類,就會編譯成一個對應的字節碼文件(.class文件)

其中,字節碼文件的文件名就是每個類的類名。需要注意的是,類即使不在源文件中定義,但被源文件引用,編譯后,也會編程相應的字節碼文件。

如類A引用類C,但類C不定義在類A的源文件中,編譯后,類C也被編譯成對應的字節碼文件C.class

三 執行java源文件

執行java源文件,用java.exe執行即可

你寫的 Java 代碼是如何一步步輸出結果的?

到現在,java源程序基本執行結果,并正確打印我們期望的結果,那么,如上的步驟,我們可以總結如下:

你寫的 Java 代碼是如何一步步輸出結果的?

如上總結,已經抽象化了在JVM中的執行。接下來,我們將分析字節碼文件(.class文件)如何在虛擬機中一步一執行的。

四 JVM如何執行字節碼文件

(一)裝載字節碼文件

當 .java 源碼被 javac.exe 編譯器編譯成 .class 字節碼文件后,接下來的工作就交給JVM處理。

JVM首先通過類加載器(ClassLoader),將class文件和相關Java API加載裝入JVM,以供JVM后續處理。

在該階段中,涉及到如下一些基本概念和知識。

1.JDK,JRE和JVM關系

  • JDK(Java Development Kit),Java開發工具包,主要用于開發,在JDK7前,JDK包括JRE

  • JRE(Java Runtime Environment),Java程序運行的核心環境,包括JVM和一些核心庫

  • JVM(Java Virtual Machine),VM是一種用于計算設備的規范,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的,是JRE核心模塊。

2.JVM

JVM是一種用于計算設備的規范,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。

Java虛擬機的主要任務是裝載class文件,并執行其中的字節碼,不同的Java虛擬機中,執行引擎可能有不同的實現。

大致有如下幾種引擎:

  • 一次性解釋字節碼引擎

  • 即時編譯引擎

  • 自適應優化器

關于虛擬機的實現方式,采用軟件方式、硬件方式和軟件硬件結合方式,這個要根據具體廠商而定。

3.什么是ClassLoader

虛擬機的主要任務是裝載class文件并執行其中的字節碼,而class文件是由虛擬機的類加載器(ClassLoader)完成的,在一個Java虛擬機中有可能存在多個類加載器。

任何java運用程序,可能會使用兩種類加載器,即啟動類加載器(bootstrap)和用戶自定義類加載器。

啟動類加載器是Java虛擬機唯一實現的一部分,它又可分為原始類裝載器,系統類裝載器或默認類裝載器。 它的主要作用是從操作系統的磁盤裝載相應的類,如Java API類等。

用戶自定義裝載類,即按照用戶自定義的方式來裝載類。

你寫的 Java 代碼是如何一步步輸出結果的?

(二)將字節碼文件存儲在JVM內存區

當JAVA虛擬機運行一個程序時,它需要內存來存儲許多東西。

比如如字節碼,程序創建的對象,傳遞給方法的參數,返回值,局部變量以及運算的中間結果等,這些相關信息被組織到“ 運行時數據 ”。

根據廠商的不同,在Java虛擬機中,運行時數據區也有所不同。有些運行時數據區由線程共享,有些只能由某個特定線程共享。

運行時數據區大致可分幾個區:方法區,堆區,棧區,PC寄存器區和本地方法棧區。

在該階段中,涉及到如下基本概念和知識。

1、方法區

方法區用來存儲解析被加載的class文件的相關信息。

當虛擬裝載一個class文件后,它會從這個class文件包含的二進制數據中解析類型信息,然后將該相關信息存儲到方法區中。

2.堆

堆是用來存儲相關引用類型的,如new對象。當程序運行時,虛擬機會把所有該程序在運行時創建的對象都放到堆中。

3.PC寄存器

PC寄存器主要用來存儲線程。當新創建一個線程時,該線程都將得到一個自己的PC寄存器(程序計數器)以及一個java棧。

Java虛擬機沒有寄存器,其指令集使用Java棧來存儲中間數據。

4.棧區

棧區主要用來存儲值類型的,如基本數據類型。需要注意的是,String為引用類型,是存在堆中的。

Java棧是由許多棧幀組成的,一個棧幀包含一個Java方法調用的狀態,當線程調用一個方法時,虛擬機壓入一個新的棧幀到該線程的Java棧中,當該方法返回時,這個棧幀從Java棧中彈出。

你寫的 Java 代碼是如何一步步輸出結果的?

(三)執行引擎與運行時數據區交互

運行時數據區為執行引擎提供了執行環境和相關數據,執行引擎通過與運行時數據區交互,從而獲取執行時需要的相關信息,存儲執行的中間結果等

你寫的 Java 代碼是如何一步步輸出結果的?

(四)執行引擎與本地方法接口

當要執行本地方法時,執行引擎將調用本地方法接口來獲取相關OS本地方法。

需要注意的是,本地方法與操作系統強耦合的。

你寫的 Java 代碼是如何一步步輸出結果的?

(五)JVM在具體操作系統上執行

JVM通過調用本地接口來獲取本地方法,從而實現在具體的平臺上執行。比如在Linux系統上執行,在Window系統上執行和在Unix系統上執行。

你寫的 Java 代碼是如何一步步輸出結果的?

五  參考文獻

1、深入Java虛擬機(原書第2版)(美)Bill Venners 著  

2、Core Java Volume I – Fundamententals(10th Edition) 

3、Core Java Volume I – Advanced Features(10th Edition) 

End

作者:Alan

來源:

http://www.cnblogs.com/wangjiming/

本文版權歸作者所有

長按下圖二維碼,即刻關注【 貍貓技術窩

阿里、京東美團、字節跳動

頂尖技術專家 坐鎮

IT人打造一個 “有溫度” 的技術窩!

你寫的 Java 代碼是如何一步步輸出結果的?

原文 

http://mp.weixin.qq.com/s?__biz=MzU2Njg3OTU1Mg==&mid=2247484842&idx=1&sn=5567dae046c39dfbb84856d31715a5f5

本站部分文章源于互聯網,本著傳播知識、有益學習和研究的目的進行的轉載,為網友免費提供。如有著作權人或出版方提出異議,本站將立即刪除。如果您對文章轉載有任何疑問請告之我們,以便我們及時糾正。

PS:推薦一個微信公眾號: askHarries 或者qq群:474807195,里面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發、高性能、分布式、微服務架構的原理,JVM性能優化這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多

轉載請注明原文出處:Harries Blog? » 你寫的 Java 代碼是如何一步步輸出結果的?

贊 (0)
分享到:更多 ()

評論 0

  • 昵稱 (必填)
  • 郵箱 (必填)
  • 網址
手机彩票计划软件超稳