成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java代碼是如何在機器上運行的?

開發 后端
計算機能識別的是機器指令碼,簡稱機器碼。機器碼是二進制的,計算機可以直接識別,但與人類的語言差別太大,不容易被人理解和記憶。后來,就誕生了各種高級語言,人們用高級語言編寫程序,然后通過把程序解釋或編譯成機器碼。

 [[398253]]

本文轉載自微信公眾號「編了個程」,作者Yasin x。轉載本文請聯系編了個程公眾號。

概覽

計算機能識別的是機器指令碼,簡稱機器碼。機器碼是二進制的,計算機可以直接識別,但與人類的語言差別太大,不容易被人理解和記憶。后來,就誕生了各種高級語言,人們用高級語言編寫程序,然后通過把程序解釋或編譯成機器碼。

比如python,就是一種解釋型語言。Python程序源碼不需要編譯,可以直接從源代碼運行程序。Python解釋器將源代碼轉換為字節碼,然后把編譯好的字節碼轉發到Python虛擬機(PVM)中進行執行。

而C語言就是典型的編譯型語言,需要先用編譯器編譯成機器碼,比如我們通常用gcc來編譯C語言程序:

  1. $ gcc hello.c # 編譯 
  2. $ ./a.out # 執行 
  3. hello world! 

那Java是解釋型語言還是編譯型語言呢?

「Java是兼具編譯型語言與解釋型語言的特點的」。程序員寫好Java程序后,需要先用javac編譯成JVM可以使用的字節碼class文件。然后JVM加載class文件,逐條解釋執行。在運行過程中,部分熱點代碼會被即時編譯器編譯成機器碼。

源代碼到字節碼

Java語言的源代碼是.java為后綴的文件。當然現在有很多其它高級語言也架構在JVM上,比如groovy、kotlin等。源代碼是給人看的,易于閱讀、理解、維護。

源代碼經過編譯后得到字節碼,字節碼是給JVM用的,易于理解和識別。字節碼是以.class為后綴,其格式是JVM的一套規劃,字節碼人類對照文檔也是勉強能看懂的,只是相對Java代碼來說要難以理解一些而已。

Java與Python不同,Python不需要編譯字節碼文件(當然,Python也提供了這種操作),編譯是一個自動的過程,一般不會在意它的存在。而Java會先編譯好字節碼文件,這樣JVM直接讀字節碼文件,可以節省加載模塊的時間,提高效率。同時字節碼的形式也增加了反向工程的難度,可以保護源代碼(當然,也可以被反編譯)。

熟悉JVM的小伙伴都知道,它有一個“類加載過程”,可以說是老八股文了,經常會被面試官問到。類加載過程其實就是指的JVM從讀取一個class文件到準備好這個類,以及最后銷毀的整個過程。

所以「class文件其實是以“類”為單位的,這跟java文件有一些不同」。如果我們在一個Java文件里面聲明多個類,用Javac編譯出來會發現有多個class文件。比如我們聲明一個One.java文件:

  1. public class One { 
  2.   public class OneInner {} 
  3.   private class OnePrivateInner {} 
  4.   public static class OneStaticInner {} 
  5.   private static class OneprivateStaticInner {} 
  6.  
  7. class Two{} 

用Javac編譯后,會出現6個class文件

  1. ➜  $ ls 
  2. 'One$OneInner.class'         'One$OneStaticInner.class'          One.class   Two.class 
  3. 'One$OnePrivateInner.class'  'One$OneprivateStaticInner.class'   One.java 

字節碼到機器碼

加載和使用字節碼

前面提到,JVM會加載class文件,然后加載后的Java類會被存放于方法區(Method Area)中。從指定的類的main方法作為入口開始運行。實際運行時,虛擬機會執行方法區內的代碼,JVM會使用堆和棧來存儲運行時數據。

每當進入一個方法,Java虛擬機會在當前線程的棧中生成一個棧幀,存放局部變量以及字節碼的操作數,這個棧幀的大小是提前計算好的。

退出方法時,不管是正常返回還是異常返回,Java虛擬機均會「彈出當前線程的當前棧幀」,并將之舍棄。

Java虛擬機需要將字節碼翻譯成機器碼,才能讓機器執行。這個過程有兩種形式,一種是解釋執行,即逐條將字節碼翻譯成機器碼并執行;另一種是即時編譯(Just-In-Time compilation,JIT),即將「一個方法中」包含的所有字節碼編譯成機器碼后再執行。

分層編譯

這兩種編譯方式是怎么協作的呢?

HotSpot虛擬機包含多個即時編譯器C1、C2和Graal。其中,Graal是一個實驗性質的即時編譯器,可以通過參數 -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler啟用,并且替換C2。

C1和C2各有優劣,適用于不同的場景。在Java 7以前,只能選擇一種編譯器。C1編譯快,但生成的代碼執行效率一般,常用于對于執行時間較短的,或者對啟動性能有要求的程序,常用于客戶端;C2編譯慢,但生成的代碼執行效率快,適用于對于執行時間較長的,或者對峰值性能有要求的程序,常用于服務端。實際上,C1對應的參數是client,C2對應的參數是server,也跟它們的應用場景比較匹配。

Java7引入了分層編譯的概念,綜合了C1的啟動性能優勢和C2的峰值性能優勢。C1和C2編譯出的機器碼是不同的。C2代碼的執行效率要比C1代碼高出30%以上。機器碼越快,需要的編譯時間就越長。分層編譯是一種折衷的方式,既能夠滿足部分不那么熱的代碼能夠在短時間內編譯完成,也能滿足很熱的代碼能夠擁有最好的優化。

熱點代碼

那怎么判定熱點代碼呢?

JVM會收集方法的運行時信息,主要包括調用次數和循環回邊的次數。當「方法的調用次數和循環回邊的次數的和,超過指定閾值時」,便會觸發即時編譯。

->

循環回邊次數可以簡單理解為方法內部代碼的循環次數,比如方法內部有for循環或while循環。

<-

在分層編譯出現前,這個閾值是由參數-XX:CompileThreshold指定的,使用C1時,該值為1500;使用C2時,該值為10000。

當啟用分層編譯時,JVM使用另一套閾值系統。在這套系統中,閾值的大小是動態調整的。JVM將閾值與某個系數 s 相乘。該系數與當前待編譯的方法數目成正相關,與編譯線程的數目成負相關。

編譯線程

默認情況下編譯線程的總數目是根據處理器數量來調整的。Java 虛擬機會將這些編譯線程按照1:2的比例分配給 C1和C2(至少各為1個)。舉個例子,對于一個四核機器來說,總的編譯線程數目為3,其中包含一個C1編譯線程和兩個C2編譯線程。

->

機器資源太少的時候,也可能各1個線程。

<-

用arthas可以看到編譯線程:

^arthas^

可以看到,它們的ID是-1,優先級也是-1。我們自己創建的線程優先級是0~10,所以編譯線程的優先級會更高一些。

總結

一句話來總結Java程序是怎么在機器上運行的呢?首先Java程序員編寫Java代碼,然后Java代碼會被編譯成class文件,多個class文件會被打包成jar包或者war包。然后JVM加載class文件,然后先解釋執行為字節碼。程序運行一段時間后,JVM會通過方法調用次數和循環持續判斷一個方法是否為熱點代碼,如果是,會使用分層編譯,通過編譯線程編譯成字節碼,在機器上運行。

責任編輯:武曉燕 來源: 編了個程
相關推薦

2014-03-31 09:45:33

Ubuntu LinuUbuntu 13.1

2017-09-18 10:05:15

WindowsLinux容器

2021-08-09 09:00:00

Kubernetes云計算架構

2021-02-25 08:00:00

WindowsWindows 10開發

2022-09-13 08:40:24

AndroidLinux

2017-02-16 10:15:43

Windows7docker變量

2019-05-09 09:00:00

WindowsKafka

2019-02-26 10:15:13

GitHub 開源代碼

2017-04-04 20:31:05

AWS GPUJupyter not深度學習

2023-02-10 21:12:41

GPUmacOSStable

2009-04-16 09:59:16

Google App PHPJava

2019-11-26 09:20:47

LinuxJava

2016-08-02 10:34:17

LinuxWindows雙啟動

2014-10-11 11:30:43

CentOSDocker

2020-05-25 17:40:00

MacpyenvPython

2020-07-08 15:29:05

MacJava編程語言

2018-07-30 09:42:09

AndroidWineWindows App

2021-08-27 11:03:57

Azure公有云云原生

2017-01-06 22:50:23

LinuxUbuntu 16.1Unity 8

2020-06-24 10:15:05

機器學習RancherKubeflow
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久不射电影网 | 91精品国产欧美一区二区成人 | av资源中文在线天堂 | 日本黄色短片 | 国产福利资源在线 | 久久久网 | 欧美高清视频一区 | 免费一区二区三区 | 一区二区成人 | 91精品国产综合久久小仙女图片 | 色在线视频网站 | 国产福利资源在线 | 91精品在线看 | 亚洲福利精品 | 福利视频一区二区三区 | 性生生活大片免费看视频 | 日韩欧美在线观看 | 国产精品一区二区精品 | 免费亚洲成人 | 亚洲成人日韩 | 一级黄色片在线免费观看 | 亚洲精品免费在线观看 | 亚洲成人午夜电影 | av综合站| 日韩欧美一区二区三区 | 91免费在线看 | 亚洲免费久久久 | 国产精品高潮呻吟久久aⅴ码 | 五月精品视频 | 手机在线观看av | 成人字幕网zmw | 欧美激情在线精品一区二区三区 | 激情五月综合 | 国产精品国产成人国产三级 | 伊人超碰 | www国产成人免费观看视频 | 国产一区二区自拍 | 久久国产一区二区三区 | 羞羞的视频在线 | 国产美女一区 | 国产成人亚洲精品自产在线 |