Java基礎——虛擬機結構

一、Java平臺結構圖




二、JVM、JRE和JDK關系


JVM:Java Virtual Machine(Java虛擬機),負責執行符合規范的Class文件

JRE: Java Runtime Environment (java運行環境),包含JVM和類庫

JDK: Java? Development Kit(java開發工具包),包含JRE和開發工具包,例如javac、javah


三、JVM所處的位置




? ? ? ?我們通常工作中所接觸的基本是Java庫和應用以及Java核心類庫,知曉如何使用就可以了,但是歸根結底代碼都是要編譯成class文件由Java虛擬機執行的,所產生的結果或者現象都可以通過Java虛擬機的運行機制來解釋。一些相同的代碼會由于虛擬機的實現不同而產生不同結果。


四、Class文件格式


? ? ? ?編譯后被Java虛擬機所執行的代碼使用了一種平臺中立(不依賴于特定硬件及操作系統的)的二進制格式來表示,并且經常(但并非絕對)以文件的形式存儲,因此這種格式被稱為Class文件格式。Class文件格式中精確地定義了類與接口的表示形式,包括在平臺相關的目標文件格式中一些細節上的慣例,例如字節序(Byte Ordering)等。

? ? ? ?正如概念所說,Java為了能夠實現平臺無關性,制定了一套自己的二進制格式,并經常以文件的方式存儲,稱為Class文件。這樣在不同平臺上,只要都安裝了Java虛擬機,那么都可以運行相同的Class文件。


五、數據類型


? ? ? ?與Java程序語言中的數據類型相似,Java虛擬機可以操作的數據類型可分為兩類:原始類型(Primitive Types,也經常翻譯為原生類型或者基本類型)和引用類型(Reference Types)。與之對應,也存在有原始值(Primitive Values)和引用值(Reference Values)兩種類型的數值可用于變量賦值、參數傳遞、方法返回和運算操作。

基本類型和引用類型的具體情況見下圖:




? ? ? ?Java虛擬機希望更多的類型檢查放在編譯期就完成,在運行期不需要進行這些操作。其中基本類型達到了這樣的要求,在運行期間不需要對其進行類型檢查,也不用和引用類型區分開。這是通過虛擬機的字節碼指令完成的,不同類型的字節碼指令中都包含了相應的數據類型。

整形類型和整型值的取值范圍如下:

? ? byte類型,取值范圍是從-128至127(-27至27-1),包括-128和127。

? ? short類型,取值范圍是從?32768至32767(-215至215-1),包括?32768和32767。

? ? int類型,取值范圍是從?2147483648至2147483647(-231至231-1),包括?2147483648和2147483647。

? long類型,取值范圍是從?9223372036854775808至9223372036854775807(-263至263-1),包括?9223372036854775808和9223372036854775807。

? ? char類型,取值范圍是從0至65535,包括0和65535。

浮點類型、取值集合和浮點值:

? ? ? ?浮點類型包含32位單精度的float類型和64位雙精度的double類型兩種,浮點數除了包括正負帶符號可數的數值,還包括了正負零、正負無窮大和一個特殊的“非數字”標識(Not-a-Number,下文用NaN表示)。NaN值用于表示某些無效的運算操作,例如除數為零等情況。所有Java虛擬機的實現都必須支持兩種標準的浮點數值集合:單精度浮點數集合和雙精度浮點數集合。

returnAddress類型和值:

? ? ? ?returnAddress類型會被Java虛擬機的jsr、ret和jsr_w指令所使用。returnAddress類型的值指向一條虛擬機指令的操作碼。與前面介紹的那些數值類的原始類型不同,returnAddress類型在Java語言之中并不存在相應的類型,也無法在程序運行期間更改returnAddress類型的值。

boolean類型:

? ? ? ?Java虛擬機不提供操作boolean類型的字節碼指令,程序在編譯后boolean類型都轉化成了int操作。但是Java虛擬機支持boolean類型的數組的訪問和修改,共用byte類型數組的字節碼指令。


六、運行時數據區


? ? ? ?Java虛擬機定義了若干種程序運行期間會使用到的運行時數據區,其中有一些會隨著虛擬機啟動而創建,隨著虛擬機退出而銷毀。另外一些則是與線程一一對應的,這些與線程對應的數據區域會隨著線程開始和結束而創建和銷毀。

Java虛擬機的邏輯構成




? ? ? ?可以看出Java虛擬機的運行時數據區包括了:方法區、Java堆、Java虛擬機棧、PC寄存器、本地方法棧

方法區

? ? ? ?方法區在虛擬機啟動的時候被創建,它存儲了每一個類的結構信息,例如運行時常量池、字段和方法數據、構造函數和普通方法的字節碼內容、還包括一些在類、實例、接口初始化時用到的特殊方法。?

方法區可能發生如下異常情況:?

? ? ? ?如果方法區的內存空間不能滿足內存分配請求,那Java虛擬機將拋出一個OutOfMemoryError異常.?

運行時常量池:?

? ? ? ?運行時常量池(Runtime Constant Pool)是每一個類或接口的常量池的運行時表示形式,它包括了若干種不同的常量:從編譯期可知的數值字面量到必須運行期解析后才能獲得的方法或字段引用。運行時常量池在方法區中。

在創建類和接口的運行時常量池時,可能會發生如下異常情況:

? ? ? ?當創建類或接口的時候,如果構造運行時常量池所需要的內存空間超過了方法區所能提供的最大值,那Java虛擬機將會拋出一個OutOfMemoryError異常。

Java堆

? ? ? ?Java堆在虛擬機啟動的時候被創建,Java堆主要用來為類實例對象和數組分配內存。Java虛擬機規范并沒有規定對象在堆中的形式。

Java堆可能發生如下異常情況:

? ? ? ?如果實際所需的堆超過了自動內存管理系統能提供的最大容量,那Java虛擬機將會拋出一個OutOfMemoryError異常。

Java虛擬機棧

? ? ? ?每個Java虛擬機線程都有自己的Java虛擬機棧。Java虛擬機棧用來存放棧幀,而棧幀主要包括了:局部變量表、操作數棧、動態鏈接。

? ? ? ?Java虛擬機使用局部變量表來完成方法調用時的參數傳遞。局部變量表的長度在編譯期已經決定了并存儲于類和接口的二進制表示中,一個局部變量可以保存一個類型為boolean、byte、char、short、float、reference 和 returnAddress的數據,兩個局部變量可以保存一個類型為long和double的數據。

? ? ? ?Java虛擬機提供一些字節碼指令來從局部變量表或者對象實例的字段中復制常量或變量值到操作數棧中,也提供了一些指令用于從操作數棧取走數據、操作數據和把操作結果重新入棧。在方法調用的時候,操作數棧也用來準備調用方法的參數以及接收方法返回結果。

? ? ? ?每個棧幀中都包含一個指向運行時常量區的引用支持當前方法的動態鏈接。在Class文件中,方法調用和訪問成員變量都是通過符號引用來表示的,動態鏈接的作用就是將符號引用轉化為實際方法的直接引用或者訪問變量的運行是內存位置的正確偏移量。?

? ? ? ?總的來說,Java虛擬機棧是用來存放局部變量和過程結果的地方。?

Java虛擬機棧可能發生如下異常情況:?

? ? ? ?如果線程請求分配的棧容量超過Java虛擬機棧允許的最大容量時,Java虛擬機將會拋出一個StackOverflowError異常。?

? ? ? ?如果Java虛擬機棧可以動態擴展,并且擴展的動作已經嘗試過,但是目前無法申請到足夠的內存去完成擴展,或者在建立新的線程時沒有足夠的內存去創建對應的虛擬機棧,那Java虛擬機將會拋出一個OutOfMemoryError異常。

PC寄存器

? ? ? ?每個Java虛擬機線程都有自己的PC寄存器。在某個線程被新建時,會獲得一個PC寄存器。線程當前執行的方法稱為當前方法,PC寄存器用來存放當前方法中當前執行的字節碼指令的地址,如果當前方法是本地方法(Native),那么寄存器存放undefined。寄存器的大小至少應該能夠存放一個returnAddress類型的數據或者與平臺相關的本地指針的值。

本地方法棧

? ? ? ?本地方法棧用于支持native方法的運行。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446998.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446998.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446998.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決 SSH Connection closed by foreign host 問題

用 Xshell 連接服務器總是報錯 : Connection closed by foreign host.Disconnected from remote host... 原因可能是 SSH 服務器沒設置保活時間間隔 , 具體設置如下 : 操作 # vim /etc/ssh/sshd_config 添加兩行 , 或去掉注釋 : ClientAliveInterval 60ClientAliveCountMax…

Java基礎——synchronized

synchronized重要!重要!重要!重要的事情說三遍,一定要記下來哦。 Java語言的關鍵字,當它用來修飾一個方法或者一個代碼塊的時候,能夠保證在同一時刻最多只有一個線程執行該段代碼。一、當兩個并發線程訪問同…

C++:MAC安裝Boost庫文件并且使用CLion開發

boost的filestem庫 C在17版本的標準庫中引入了一個filesystem庫,用來處理文件路徑,以及文件訪問。很多編譯器對filesystem庫的支持還不是很好。為了解決這個問題,可以臨時使用boost::filesystem來替代。其實C17標準中的filesystem庫就是從bo…

Java基礎——Java異常處理機制

一、引言 try…catch…finally恐怕是大家再熟悉不過的語句了,而且感覺用起來也是很簡單,邏輯上似乎也是很容易理解。不過,我親自體驗的“教訓”告訴我,這個東西可不是想象中的那么簡單、聽話。不信?那你看看下面的代碼…

clion在使用sqlite3的時候,顯示Undefined symbols for architecture x86_64錯誤的解決辦法

顯示Undefined symbols for architecture x86_64錯誤的原因 1、缺少靜態庫 環境:在模擬器上報錯但在真機上能運行成功,而且報的錯誤來自于第三方庫。原因:architecture x86_64 是指模擬器的架構,意思就是 Crypto 變量在模擬器架…

Java基礎——Java反射機制及IoC原理

一、概念 主要是指程序可以訪問,檢測和修改它本身狀態或行為的一種能力,并能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。在java中,只要給定類的名字, 那么就可以通過反射機制來獲得類的所…

Ubuntu boost庫文件安裝編譯

簡單介紹 Boost庫是為C語言標準庫提供擴展的一些C程序庫的總稱,由Boost社區組織開發、維護.Boost向來有準標準庫之稱,很多新特性例如智能指針等都是先在boost中實現,后來被吸收到標準庫之中. Boost實現了日志、算法、日期、地理、數學、線程…

Java基礎——類加載機制及原理

一、什么是類的加載? 類的加載指的是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,然后在堆區創建一個java.lang.Class對象,用來封裝類在方法區內的數據結構。類的加載的最終產品是位于堆區中的Cl…

在Ubuntu環境下使用vcpkg安裝sqlite_orm包文件

Ubuntu安裝vcpkg 從github下載vcpkg的安裝包,在usr/local路徑下面執行如下命令 git clone https://github.com/Microsoft/vcpkg.git cd vcpkg //進入源碼目錄 ./bootstrap-vcpkg.sh //執行./bootstrap-vcpkg.sh進行編譯安裝,這個過程很慢 編譯安裝好…

finally語句與return語句的執行順序

網上有很多人探討Java中異常捕獲機制try...catch...finally塊中的finally語句是不是一定會被執行?很多人都說不是,當然他們的回答是正確的,經過我試驗,至少有兩種情況下finally語句是不會被執行的: try語句沒有被執行到…

window電腦查看ssh公鑰,以及將自己的公鑰添加到Github等類似網站

查看本機的ssh公鑰 使用命令 cd ~/.ssh使用命令 ls 可以看到 id_rsa id_rsa.pub known_hosts 三個文件,此處需要的是id_rsa.pub文件使用命令 cat id_rsa.pub 查看文件的內容拷貝這段內容 添加自己的公鑰 進入賬戶的設置頁面參照如下步驟,進入SSH Key…

java八大排序算法

一、概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。 我們這里說說八大排序就是內部排序。 當n較大,則應采…

密鑰安全性討論之密鑰分層管理結構

密鑰分層管理結構 密鑰的安全管理通常采用層次化的保護方法。密鑰管理分層管理機制將密鑰分為三層,即根密鑰、密鑰加密密鑰和工作密鑰下層密鑰為上層密鑰提供加密保護,采用分層的密鑰結構有助于密鑰的管理滿足本規范的要求 工作密鑰 工作密鑰對本地保存…

windows安裝 Git Large File Storage大文件下載工具ge

下載地址 導航到 git-lfs.github.com 并單擊Download開始下載git-lfs的用法指南 驗證安裝成功 打開Git Bash驗證安裝成功,使用命令 git lfs install ,如果出現 >Git LFS initlized,就代表安裝成功參考鏈接 安裝 Git Large File Storag…

Java基礎——volatile關鍵字解析

簡介volatile關鍵字雖然從字面上理解起來比較簡單,但是要用好不是一件容易的事情。由于volatile關鍵字是與Java的內存模型有關的,因此在講述volatile關鍵之前,我們先來了解一下與內存模型相關的概念和知識,然后分析了volatile關鍵…

Linux ubuntu對于cmake的版本更新

問題產生 在ubuntu環境下運行C代碼,工程文件中CMakeLists文件顯示要求cmake的版本最低是3.15,但是我的本地版本是3.11,雖然修改CMakelists文件為3.11也是可以編譯通過,但是潛在的問題是未知的。 查看本地cmake的版本 cmake --ve…

Java基礎——Java IO詳解

一、概述 1、Java IO Java IO即Java 輸入輸出系統。不管我們編寫何種應用,都難免和各種輸入輸出相關的媒介打交道,其實和媒介進行IO的過程是十分復雜的,這要考慮的因素特別多,比如我們要考慮和哪種媒介進行IO(文件、控…

Java基礎——Java NIO詳解(二)

一、簡介 在我的上一篇文章Java NIO詳解(一)中介紹了關于標準輸入輸出NIO相關知識, 本篇將重點介紹基于網絡編程NIO(異步IO)。 二、異步IO 異步 I/O 是一種沒有阻塞地讀寫數據的方法。通常,在代碼進行 rea…

Java基礎——Java NIO詳解(一)

一、基本概念 1、I/0簡介 I/O即輸入輸出,是計算機與外界世界的一個借口。IO操作的實際主題是操作系統。在java編程中,一般使用流的方式來處理IO,所有的IO都被視作是單個字節的移動,通過stream對象一次移動一個字節。流IO負責把對象…