自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java程序員必備基礎:Java代碼是怎么運行的?

開發(fā) 后端
作為一名Java程序員,我們需要知道Java代碼是怎么運行的。最近復習了深入理解Java虛擬機,做了一下總結,希望對大家有幫助,如果有不正確的地方,歡迎提出,感激不盡。

 前言

作為一名Java程序員,我們需要知道Java代碼是怎么運行的。最近復習了深入理解Java虛擬機,做了一下總結,希望對大家有幫助,如果有不正確的地方,歡迎提出,感激不盡。

[[318672]]

java 代碼運行主要流程

 

本文主要講解流程如下:

  • java源文件編譯為class字節(jié)碼
  • 類加載器把字節(jié)碼加載到虛擬機的方法區(qū)。
  • 運行時創(chuàng)建對象
  • 方法調(diào)用,執(zhí)行引擎解釋為機器碼
  • CPU執(zhí)行指令
  • 多線程切換上下文

編譯

我們都知道,java代碼是運行在Java虛擬機上的。但是java是一門面向?qū)ο蟮母呒壵Z言,它不僅語法非常復雜,抽象程度也非常高,并不能直接運行在計算機硬件機器上。

Java虛擬機(Java Virtual Machine 簡稱JVM)是運行所有Java程序的抽象計算機,是Java語言的運行環(huán)境。

因此,在運行Java程序之前,需要編譯器把代碼編譯成java虛擬機所能識別的指令程序,這就是Java字節(jié)碼,即class文件。

所以,Java代碼運行的第一步是:把Java源代碼編譯成.class 字節(jié)碼文件。

 

類加載

在Class文件中描述的各種信息,需要被加載到虛擬機之后才能運行和使用。因此,需要把class字節(jié)碼文件加載到Java虛擬機來。

虛擬機把描述類的數(shù)據(jù)從 Class 文件加載到內(nèi)存,并對數(shù)據(jù)進行校驗、轉(zhuǎn)換解析和初始化,最終形成可以被虛擬機直接使用的 Java 類型,這就是虛擬機的類加載機制。

加載

在加載階段,虛擬機需要完成以下3件事情:

  • 通過一個類的全限定名來獲取定義此類的二進制字節(jié)流。
  • 將這個字節(jié)流所代表的靜態(tài)存儲結構轉(zhuǎn)化為方法區(qū)的運行時數(shù)據(jù)結構。
  • 在內(nèi)存中生成一個代表這個類的java.lang.Class對象,作為方法區(qū)這個類的各種數(shù)據(jù)的訪問入口

加載階段完成后,這些二進制字節(jié)流按照虛擬機所需的格式存儲在方法區(qū)之中。

 

驗證

為了確保Class文件的字節(jié)流中包含的信息符合當前虛擬機的要求,不會危害虛擬機的安全,Java虛擬機對輸入的字節(jié)流走驗證過程。

驗證階段包括四個階段:文件格式驗證、元數(shù)據(jù)驗證、字節(jié)碼驗證、符號引用驗證。

 

  • 文件格式驗證: 驗證字節(jié)流是否符合Class文件格式規(guī)范,如:是否以魔數(shù)0xCAFEBABE開頭。
  • 元數(shù)據(jù)驗證: 對字節(jié)碼描述的信息進行語義分析,如:這個類的父類是否繼承了不允許被繼承的類(被final修飾的類);
  • 字節(jié)碼驗證: 主要目的是通過數(shù)據(jù)流和控制流分析,確定程序語義是合法的、符合邏輯的。如:保證跳轉(zhuǎn)指令不會跳轉(zhuǎn)到方法體以外的字節(jié)碼指令上。
  • 符號引用驗證: 發(fā)生在虛擬機將符號引用轉(zhuǎn)化為直接引用的時候,如:校驗符號引用中通過字符串描述的全限定名是否能找到對應的類。

準備

準備階段是正式為類變量分配內(nèi)存并設置類變量初始值,這些變量所使用的內(nèi)存都將在方法區(qū)中進行分配。如:

 

  1. public static int value =123; 

變量value在準備階段過后的初始值是0而不是123。

解析

解析階段是虛擬機將常量池內(nèi)的符號引用替換為直接引用的過程。

比如:com.User類引用com.Tool類,在編譯時,User類不知道Tool類的實際內(nèi)存地址,因此只能使用符號com.Tool(假設)來表示。而在類加載加載User類的時候,可以通過虛擬機獲取Tool類的實際內(nèi)存地址,因此便可以將符號com.Tool替換為Tool類的實際內(nèi)存地址,即直接引用地址。

解析動作主要針對類或接口、字段、類方法、接口方法、方法類型、方法句柄和調(diào)用點限定符 7 類符號引用進行。

初始化

到了初始化階段,才真正開始執(zhí)行類中定義的Java字節(jié)碼。在這個階段,則根據(jù)程序員通過程序制定的主觀計劃去初始化類變量和其他資源。

創(chuàng)建對象

Java虛擬機是如何執(zhí)行字節(jié)碼的呢?我們先來看一下運行時創(chuàng)建對象。

Java是面向?qū)ο蟮木幊陶Z言,程序的運行是以對象為調(diào)用單位的。

  • 字節(jié)碼文件加載到虛擬機的方法區(qū)后,在程序運行過程,通過 class字節(jié)碼文件創(chuàng)建與其對應的對象信息 。
  • 創(chuàng)建對象的方式有:new關鍵字,反射等。
  • Java堆內(nèi)存是線程共享的區(qū)域,創(chuàng)建后的對象信息就保存在Java堆內(nèi)存中。

 

方法調(diào)用

JVM的調(diào)用單位是對象,但是真正執(zhí)行功能性的代碼還是對象上的方法。

在運行過程中,每當調(diào)用進入一個java方法,java虛擬機會在當前線程的java方法棧中生成一個棧幀,用以存放局部變量以及字節(jié)碼的操作數(shù)。方法棧內(nèi)存是線程私有的,每個線程都有自己的方法棧。如果對應的方法是本地方法,則對應的就是本地方法棧。

java運行時數(shù)據(jù)區(qū)域如下:

 

解釋

當調(diào)用Java對象的某個方法時,JVM執(zhí)行引擎會將該方法的字節(jié)碼文件翻譯成計算機所能識別的機器碼,機器碼信息保存在方法區(qū)中。翻譯有解釋執(zhí)行和即時編譯兩種方式。

 

種翻譯方式的區(qū)別如下:

解釋執(zhí)行

 

來一行代碼,解釋一行,大部分不常用的代碼,都是采用這種方式。

即使編譯

對于部分熱點代碼,將一個方法包含的所有字節(jié)碼翻譯成機器指令,以提高java虛擬機的運行效率。

即時編譯是建立經(jīng)典的二八定律上,即20%代碼占據(jù)了80%的計算資源。

執(zhí)行指令

 

  • Java程序被加載入內(nèi)存后,指令也在內(nèi)存中了。
  • 指令的指令寄存器IP,指向下一條待執(zhí)行指令的地址。
  • CPU的控制單元根據(jù)IP寄存器的指向,將主存中的指令裝載到指令寄存器,這些加載的指令就是一串二進制碼,還需要譯碼器進行解碼。
  • 解碼后,如果需要獲取操作數(shù),則從內(nèi)存中取數(shù)據(jù),調(diào)用運算單元進行計算。

多線程上下文切換

CPU一通上電,就會周而復始從內(nèi)存中獲取指令、譯碼、執(zhí)行。

 

  • 為了支持多任務,CPU 將執(zhí)行時間這個資源劃分成時間片,每個程序執(zhí)行一段時間。
  • java虛擬機的多線程是通過線程輪流切換分配處理執(zhí)行時間的方式來實現(xiàn)的,在任何一個確定的時刻,一個處理器(對于多核處理器來說是一個內(nèi)核)都只會執(zhí)行一條程序中的指令。
  • 假設當前線程在運行中,CPU分配的時間執(zhí)行完了,總得保存運行過的結果信息吧,要不然白白浪費之前的工作了,因此,程序計數(shù)器(PC寄存器)作用體現(xiàn)出來了,它是一塊較小的內(nèi)存空間,線程私有,可以看作當前線程執(zhí)行的字節(jié)碼的行號指示器。當CPU又給它分配時間跑的時候,可以把數(shù)據(jù)恢復,接著上一次執(zhí)行到的位置繼續(xù)執(zhí)行就可以了。

 

責任編輯:華軒 來源: 撿田螺的小男孩
相關推薦

2020-05-09 11:20:02

Java結構圖虛擬機

2020-01-12 19:10:30

Java程序員數(shù)據(jù)

2020-05-06 15:59:07

JavaScript程序員技術

2009-06-25 09:33:43

Java API程序員

2009-07-02 15:10:17

Java程序員面試

2020-07-20 07:46:01

程序員加簽驗簽

2023-10-04 00:50:00

Java開發(fā)

2019-07-05 10:45:27

Java程序員編程語言

2015-08-20 14:34:25

程序員java基礎網(wǎng)絡編程

2022-10-24 09:00:47

畫圖工具程序員XMind

2013-06-08 14:12:13

程序員招聘

2019-12-16 09:42:56

Java匿名類多線程

2015-01-22 16:16:35

AdroidJava工具

2021-02-20 11:04:40

C++VS代碼調(diào)試

2020-04-20 19:00:30

程序員分布式事務架構

2020-04-20 11:19:00

Java開發(fā)序列化

2019-07-19 10:04:05

Java程序員Tomcat

2022-03-17 10:24:28

JavaJVM

2014-07-29 10:30:16

JavaJava程序員

2012-11-02 13:47:31

Java程序員編程
點贊
收藏

51CTO技術棧公眾號