JVM 基礎—進階知識點總結:基礎知識、字節碼、類加載器

1. JDK、JRE、JVM的關係

1.1 JDK

JDK(Java Development Kit) 是用於開發 Java 應用程序的軟件開發工具集合,包括 了 Java 運行時的環境(JRE)、解釋器(Java)、編譯器(javac)、Java 歸檔 (jar)、文檔生成器(Javadoc)等工具。簡單的說我們要開發Java程序,就需要安裝某個版本的JDK工具包。

1.2 JRE

JRE(Java Runtime Enviroment )提供 Java 應用程序執行時所需的環境,由 Java 虛擬機(JVM)、核心類、支持文件等組成。簡單的說,我們要是想在某個機器上運 行Java程序,可以安裝JDK,也可以只安裝JRE,後者體積比較小。

1.3 JVM

Java Virtual Machine(Java 虛擬機)有三層含義,分別是:

JVM規範要求

滿足 JVM 規範要求的一種具體實現(一種計算機程序)

一個 JVM 運行實例,在命令提示符下編寫 Java 命令以運行 Java 類時,都會創建一 個 JVM 實例,我們下面如果只記到JVM則指的是這個含義;如果我們帶上了某種JVM 的名稱,比如說是Zing JVM,則表示上面第二種含義

我這邊也整理了一份 架構師全套****和關於java的系統化資料,包括java核心知識點、面試專題和20年最新的互聯網真題、電子書等都有。有需要的朋友可以點一點下方鏈接免費領取!

鏈接:1103806531暗號:CSDN

在這裏插入圖片描述

1.4 JDK 與 JRE、JVM 之間的關係

就範圍來說,JDK > JRE > JVM:

  • JDK = JRE + 開發工具
  • JRE = JVM + 類庫

在這裏插入圖片描述在這裏插入圖片描述

Java程序的開發運行過程爲:

我們利用 JDK (調用 Java API)開發Java程序,編譯成字節碼或者打包程序 然後可以用 JRE 則啓動一個JVM實例,加載、驗證、執行 Java 字節碼以及依賴庫, 運行Java程序。

而JVM 將程序和依賴庫的Java字節碼解析並變成本地代碼執行,產生結果 。

1.5 如果不知道自動安裝/別人安裝的JDK在哪個目錄怎麼辦?

最簡單/最麻煩的查詢方式是詢問相關人員。

查找的方式很多,比如,可以使用 which , whereis , ls ‐l 跟蹤軟連接, 或者 find 命令全局查找(可能需要sudo權限), 例如:

  • jps ‐v
  • whereis javac
  • ls ‐l /usr/bin/javac
  • find / ‐name javac

2. JVM基礎知識

2.1 常見的編程語言類型

首先,我們可以把形形色色的編程從底向上劃分爲最基本的三大類:機器語言、彙編 語言、高級語言。
在這裏插入圖片描述
按《計算機編程語言的發展與應用》一文裏的定義:計算機編程語言能夠實現人與機器之間的交流和溝通,而計算機編程語言主要包括彙編語言、機器語言以及高級語言,具體內容如下:

  • 機器語言:這種語言主要是利用二進制編碼進行指令的發送,能夠被計算機快速地識別,其靈活性相對較高,且執行速度較爲可觀,機器語言與彙編語言之間的相似性較高,但由於具有侷限性,所以在使用上存在一定的約束性。
  • 彙編語言:該語言主要是以縮寫英文作爲標符進行編寫的,運用匯編語言進行編 寫的一般都是較爲簡練的小程序,其在執行方面較爲便利,但彙編語言在程序方面較爲冗長,所以具有較高的出錯率。
  • 高級語言:所謂的高級語言,其實是由多種編程語言結合之後的總稱,其可以對多條指令進行整合,將其變爲單條指令完成輸送,其在操作細節指令以及中間過 程等方面都得到了適當的簡化,所以,整個程序更爲簡便,具有較強的操作性, 而這種編碼方式的簡化,使得計算機編程對於相關工作人員的專業水平要求不斷放寬。

2.2 高級語言分類

如果按照有沒有虛擬機來劃分,高級編程語言可分爲兩類:

  • 有虛擬機:Java,Lua,Ruby,部分JavaScript的實現等等
  • 無虛擬機:C,C++,C#,Golang,以及大部分常見的編程語言

如果按照變量是不是有確定的類型,還是類型可以隨意變化來劃分,高級編程語言可以分爲:

  • 靜態類型:Java,C,C++等等
  • 動態類型:所有腳本類型的語言

如果按照是編譯執行,還是解釋執行,可以分爲:

  • 編譯執行:C,C++,Golang,Rust,C#,Java,Scala,Clojure,Kotlin, Swift…等等
  • 解釋執行:JavaScript的部分實現和NodeJS,Python,Perl,Ruby…等等

此外,我們還可以按照語言特點分類:

  • 面向過程:C,Basic,Pascal,Fortran等等
  • 面向對象:C++,Java,Ruby,Smalltalk等等
  • 函數式編程:LISP、Haskell、Erlang、OCaml、Clojure、F#等等
  • 有的甚至可以劃分爲純面嚮對象語言,例如Ruby,所有的東西都是對象(Java不是所有東西都是對象,比如基本類型 int 、 long 等等,就不是對象,但是它們的包裝 類 Integer 、 Long 則是對象)。 還有既可以當做編譯語言又可以當做腳本語言的,例如Groovy等語言。

2.3 關於跨平臺

現在我們聊聊跨平臺,爲什麼要跨平臺,因爲我們希望所編寫的代碼和程序,在源代碼級別或者編譯後,可以運行在多種不同的系統平臺上,而不需要爲了各個平臺的不 同點而去實現兩套代碼。典型地,我們編寫一個web程序,自然希望可以把它部署到 Windows平臺上,也可以部署到Linux平臺上,甚至是MacOS系統上。 這就是跨平臺的能力,極大地節省了開發和維護成本,贏得了商業市場上的一致好評。

這樣來看,一般來說解釋型語言都是跨平臺的,同一份腳本代碼,可以由不同平臺上的解釋器解釋執行。但是對於編譯型語言,存在兩種級別的跨平臺: 源碼跨平臺和二進制跨平臺。

1、典型的源碼跨平臺(C++):
在這裏插入圖片描述
2、典型的二進制跨平臺(Java字節碼):
在這裏插入圖片描述
可以看到,C++裏我們需要把一份源碼,在不同平臺上分別編譯,生成這個平臺相關的二進制可執行文件,然後才能在相應的平臺上運行。 這樣就需要在各個平臺都有開發工具和編譯器,而且在各個平臺所依賴的開發庫都需要是一致或兼容的。 這一點在過去的年代裏非常痛苦,被戲稱爲 「依賴地獄」。 C++的口號是「一次編寫,到處(不同平臺)編譯」,但實際情況上是一編譯就報錯,變 成了 「一次編寫,到處調試,到處找依賴、改配置」。 大家可以想象,你編譯一份代 碼,發現缺了幾十個依賴,到處找還找不到,或者找到了又跟本地已有的版本不兼 容,這是一件怎樣令人絕望的事情。

而Java語言通過虛擬機技術率先解決了這個難題。 源碼只需要編譯一次,然後把編譯 後的class文件或jar包,部署到不同平臺,就可以直接通過安裝在這些系統中的JVM上 面執行。 同時可以把依賴庫(jar文件)一起復制到目標機器,慢慢地又有了可以在各個平臺都直接使用的Maven中央庫(類似於linux裏的yum或apt­get源,macos裏的 homebrew,現代的各種編程語言一般都有了這種包依賴管理機制:python的pip, dotnet的nuget,NodeJS的npm,golang的dep,rust的cargo等等)。這樣就實現了 讓同一個應用程序在不同的平臺上直接運行的能力。

總結一下跨平臺:

  • 腳本語言直接使用不同平臺的解釋器執行,稱之爲腳本跨平臺,平臺間的差異由不同平臺上的解釋器去解決。這樣的話代碼很通用,但是需要解釋和翻譯,效率較低。
  • 編譯型語言的代碼跨平臺,同一份代碼,需要被不同平臺的編譯器編譯成相應的二進制文件,然後再去分發和執行,不同平臺間的差異由編譯器去解決。編譯產 生的文件是直接針對平臺的可執行指令,運行效率很高。但是在不同平臺上編譯 複雜軟件,依賴配置可能會產生很多環境方面問題,導致開發和維護的成本較高。
  • 編譯型語言的二進制跨平臺,同一份代碼,先編譯成一份通用的二進制文件,然後分發到不同平臺,由虛擬機運行時來加載和執行,這樣就會綜合另外兩種跨平臺語言的優勢,方便快捷地運行於各種平臺,雖然運行效率可能比起本地編譯類 型語言要稍低一點。 而這些優缺點也是Java虛擬機的優缺點。

2.4 關於運行時(Runtime)與虛擬機(VM)

我們前面提到了很多次 Java運行時 和 JVM虛擬機 ,簡單的說JRE就是Java的運行 時,包括虛擬機和相關的庫等資源。 可以說運行時提供了程序運行的基本環境,JVM在啓動時需要加載所有運行時的核心庫等資源,然後再加載我們的應用程序字節碼,才能讓應用程序字節碼運行在JVM這 個容器裏。

但也有一些語言是沒有虛擬機的,編譯打包時就把依賴的核心庫和其他特性支持,一 起靜態打包或動態鏈接到程序中,比如Golang和Rust,C#等。 這樣運行時就和程序指令組合在一起,成爲了一個完整的應用程序,好處就是不需要虛擬機環境,壞處是編譯後的二進制文件沒法直接跨平臺了。

2.5 關於內存管理和垃圾回收(GC)

內存管理就是內存的生命週期管理,包括內存的申請、壓縮、回收等操作。 Java的內存管理就是GC,JVM的GC模塊不僅管理內存的回收,也負責內存的分配和壓縮整理。

最後

由於篇幅有限,這裏只展示一部分,完整版我已經整理成了文檔,有需要的朋友可以點一點下方鏈接免費領取

鏈接:1103806531暗號:CSDN

在這裏插入圖片描述