JVM深入理解

3864a7da14a7498fa942782256d5c12f.gifJVM深入理解(一)

?

?

JVM是什么

JRE、JDK和JVM 的關系

JVM原理

1、JVM是什么?

?

  JVM是Java Virtual Machine(Java虛擬機)的縮寫,由一套字節碼指令集、一組寄存器、一個棧、一個垃圾回收堆和一個存儲方法域等組成。

?

  他是幫助我們將java代碼 生成編譯后 的 class 文件。?

?

?

?

2、JRE、JDK和JVM 的關系  

?

  JRE(Java Runtime Environment, Java運行環境)是Java平臺,所有的程序都要在JRE下才能夠運行。包括JVM和Java核心類庫和支持文件。

?

  JDK(Java Development Kit,Java開發工具包)是用來編譯、調試Java程序的開發工具包。包括Java工具(javac/java/jdb等)和Java基礎的類庫(java API )。

?

  JVM(Java Virtual Machine, Java虛擬機)是JRE的一部分。JVM主要工作是解釋自己的指令集(即字節碼)并映射到本地的CPU指令集和OS的系統調用。Java語         言是跨平臺運行的,不同的操作系統會有不同的JVM映射規則,使之與操作系統無關,完成跨平臺性。

?

?

?

  JDK

?

  JDK(Java Development Kit) 是 Java 語言的軟件開發工具包(SDK)。JDK 物理存在,是 programming tools、JRE 和 JVM 的一個集合。

?

  

  JRE

?

  JRE(Java Runtime Environment)Java 運行時環境,JRE 物理存在,主要由Java API 和 JVM 組成,提供了用于執行 java 應用程序最低要求的環境。

?

  

?

?

3、JVM原理

?

  3.1、JVM的體系結構

?

  

  3.2、JVM生命周期介紹

?

  3.2.1 啟動:

?

  啟動一個JAVA程序,一個JVM實例就會產生。例如我們通常用到的main() 方法一樣。

?

  3.2.2 運行:

?

  用main() 作為程序初始線程的起點,任何其他線程均可由該線程啟動。JVM內部有兩種線程:守護線程和非守護線程。

?

  main() 屬于非守護線程,守護線程通常由JVM使用,程序可以指定創建的線程為守護線程。

?

  3.2.3 消亡:

?

  當程序中的所有非守護線程都終止時,JVM才退出;若安全管理器允許,程序也可以使用Runtime類或者System.exit退出。

?

  JVM執行引擎實例則對應了屬于用戶運行程序線程它是線程級別的。

?

?

?

  3.3、JAVA類加載器

?

  Java加載類的過程:

?

  

  3.3.1、裝載(Loading)

?

  負責找到二進制字節碼并加載到JVM中,JVM通過類名、類所在的包名、ClassLoader完成類的加載。因此,標識一個被加載了的類:類名 + 包名 + ClassLoader實例ID。 

?

  3.3.2、鏈接(Linking)

?

  負責對二進制字節碼的格式進行校驗、初始化裝載類中的靜態變量以及解析類中調用的接口。

?

  完成校驗后,JVM初始化類中的靜態變量,并將其賦值為默認值。

?

  最后對比類中的所有屬性、方法進行驗證,以確保要調用的屬性、方法存在,以及具備訪問權限(例如private、public等),否則會造成NoSuchMethodError、    NoSuchFieldError等錯誤信息。

?

  3.3.3、初始化(Initializing)

  負責執行類中的靜態初始化代碼、構造器代碼以及靜態屬性的初始化,以下四種情況初始化過程會被觸發。

?

?

  3.4、JVM類加載順序

?

  層級結構

?

  

  1.Booststrap ClassLoader

?

  跟ClassLoader,C++實現,JVM啟動時初始化此ClassLoader,并由此完成$JAVA_HONE中jre/lib/rt.jar(Sun JDK的實現)中所有class文件的加載,這個jar中包含了java規范定義的所有接口以及實現。

?

  2.Extension ClassLoader

?

  JVM用此classloader來加載擴展功能的一些jar包

?

  3.System ClassLoader

?

  JVM用此ClassLoader來加載啟動參數中指定的ClassPath中的jar包以及目錄,在Sun JDK中ClassLoader對應的類名為AppClassLoader。

?

  4.User-Defined ClassLoader

?

  User-Defined ClassLoader是Java開發人員繼承ClassLoader抽象類實現的ClassLoader,基于自定義的ClassLoader可用于加載非ClassPath中的jar以及目錄。

?

  

?

  3.5、委派模式(Delegation Mode)

?

  

  當JVM加載一個類的時候,下層的加載器會將任務給上一層類加載器,上一層加載檢查它的命名空間中是否已經加載這個類,如果已經加載,直接使用這個類。如果沒有加載,繼續往上委托直到頂部。檢查之后,按照相反的順序進行加載。如果Bootstrap加載器不到這個類,則往下委托,直到找到這個類。一個類可以被不同的類加載器加載。

?

  可見性限制:下層的加載器能夠看到上層加載器中的類,反之則不行,委派只能從下到上。

?

  不允許卸載類:類加載器可以加載一個類,但不能夠卸載一個類。但是類加載器可以被創建或者刪除。

?

?

?

  3.6、JVM執行引擎

?

  類加載器將字節碼載入內存后,執行引擎以java字節碼為單元,讀取java字節碼。java字節碼機器讀不懂,必須將字節碼轉化為平臺相關的機器碼。這個過程就是由執行引擎完成的。

?

  

  在執行方法時JVM提供了四種指令來執行

?

  invokestatic:調用類的static方法。

?

  invokevirtual:調用對象實例的方法。

?

  invokeinterface:將屬性定義為接口來進行調用。

?

  invokespecial:JVM對于初始化對象(Java構造器的方法為:)以及調用對象實例的私有方法時。

?

  主要的執行計數:

?

  解釋,即時執行,自適應優化、芯片級直接執行。

?

  解釋屬于第一代JVM

?

  即時編譯JIT屬于第二代JVM

?

  自適應優化(目前sun的HotspotJVM采用這種技術),吸取第一代JVM和第二代JVM的經驗,采用兩者結合的方式,開始對所有的代碼都采用解釋執行的方式,并監視代碼執行情況,然后對那些經常調用的方法啟動一個后臺線程,將其編譯為本地代碼,并進行優化。若方法不再頻繁使用,則取消編譯過代碼,仍對其進行解釋執行。

?

  

?

  3.7、Java運行時數據區

?

  

  PC寄存器

?

  用于存儲每個線程下一步將要執行的JVM指令,若該方法為native的,則PC寄存器中不存儲任何信息。Java多線程情況下,每個線程都有一個自己的PC,以便完成不同線程上下文環境的切換

?

  JVM棧 

?

JVM棧是線程私有的,每個線程創建的同時都會創建JVM棧,JVM棧中存放當前線程中局部基本類型的變量(Java中定義的八種基本類型:boolean、char、byte、short、int、long、float、double)、部分的返回結果以及Stack Frame,非基本類型的對象在JVM棧上僅存放一個指向堆的地址。

  堆(Heap)

?

它是JVM用來存儲對象實例以及數組值的區域,可以認為Java中所有通過new創建的對象的內存都在此分配,Heap中的對象的內存需要等待GC進行回收。

?

堆在JVM啟動的時候就被創建,堆中儲存了各種對象,這些對象被自動管理內存系統(Automatic Storage Management System),也就是常說的“Garbage Collector(垃圾回收器)”管理。這些對象無需、也無法顯示地被銷毀。

?

JVM將Heap分為兩塊:新生代New Generation和舊生代Old Generation

?

    

  堆是JVM中所有線程共享的,因此在其上進行對象內存的分配均需要進行加鎖,導致new對象的開銷比較大。

?

  Sun Hotspot JVM為了提升對象內存分配的效率,對于所有創建的線程都會分配一塊獨立的空間TLAB(Thread Local Allocation Buffer),其大小由JVM根據運行的情況計算而得,在TLAB上分配對象時不需要加鎖,因此JVM在給線程對象分配內存時會盡量的在TLAB上分配,在這種情況下JVM中分配對象內存的性能和C基本是一樣的,但如果對象過大的話則仍然要直接使用堆空間分配。

?

  TLAB僅作用于新生代的Eden Space,因此在編寫Java程序時,通常多個小的對象比大的對象分配起來更加高效。

?

  所有新創建的Object都將會存儲在新生代Young Generation中。如果Young Generation的數據在一次或多次GC后存活下來,那么將被轉移到OldGeneration。新的Object總是創建在Eden Space。

?

  方法區域(Method Area)

  在Sun JDK中這塊區域對應的為PermanetGeneration,又稱為持久代。

?

  方法區域存放所加載類的信息(名稱、修飾符等)、類中的靜態變量、類中定義為final類型的常量、類中的Field信息、類中的方法信息,當開發人員在程序中通過Class對象中的getName,isInstance等方法來獲取信息時,這些數據都來源于方法區域,同時方法區域也是全局共享的,在一定條件下它也會被GC,當方法區域需要使用的內存超過其允許的大小時,就會拋出OutOfMemory的錯誤信息。

?

  運行時常量池(Runtime Constant Pool)

?

存放的為類中的固定常量信息、方法和Field的引用信息等,其空間從方法區域中分配。

?

  本地方法堆棧(Native Method Stacks)

?

JVM采用本地方法堆來支持native方法的執行,此區域用于存儲每個native方法調用的狀態。

?

  

  3.8、JVM垃圾回收

  GC的基本原理:將內存中不再被使用的對象進行回收,GC中用于回收的方法稱為收集器,由于GC需要消耗一些資源和時間,Java在對對象生命周期特征進行分析后,按照新生代、舊生代的方式來對對象進行收集,以盡可能的縮短GC對應用造成的暫停。

?

  對新生代的對象收集稱為minor GC

?

  對舊生代的對象收集稱為Full GC

?

  程序中主動調用System.gc()強制執行的GC為Full GC。

?

  不同的對象引用類型,GC會采用不同的方法進行回收,JVM對象的引用分為了四種類型:

?

  強引用:默認情況下,對象采用的均為強引用(這個對象的實例沒有其他對象引用時, GC時才會被回收)

?

  軟引用:軟引用是Java中提供的一種比較適合于緩存場景的應用(只有內存不夠的情況下才會被GC)

?

  弱引用:在GC時一定會被GC回收。

?

 

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

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

相關文章

MediaCodec詳解

MediaCodec 是Android平臺提供的一個API,用于對音頻和視頻數據進行編碼(轉換為不同的格式)和解碼(從一種格式轉換回原始數據)。它是Android 4.1(API級別16)及以上版本的一部分,允許開…

Sulfo-CY5 Azide在其他生物學研究中的應用

除了生物成像、生物分子標記、分子生物學研究和生物傳感與診斷等領域外,Sulfo-CY5 Azide還在其他生物學研究中有多種應用,**(來自星戈瑞的花菁染料)**如下: ****細胞追蹤和細胞遷移研究:****Sulfo-CY5 Azide可以被用作細胞標記劑&…

【教3妹學編程-算法題】統計和小于目標的下標對數目

2哥 : 3妹,OpenAI的宮斗劇迎來了大結局!OpenAI宣布阿爾特曼復職CEO,董事會重組 3妹:啊?到底誰才是幕后操縱者啊,有咩有揪出來 2哥 : 也不是很清楚,據說在被開除的幾周前,前CEO曾譴責…

Linux 家目錄和根目錄

摘要: 在 Linux 操作系統中,家目錄和根目錄是兩個非常重要的概念。它們是 Linux 文件系統中的兩個關鍵節點,為用戶和系統進程提供存儲、管理和訪問文件和目錄的接口。本文旨在深入探討和理解這兩個目錄的結構、功能和使用方式,同時…

行情分析 - - 加密貨幣市場大盤走勢(11.24)

大餅昨日震蕩幅度很小,而今天延續昨日的空頭思路。當然如果從MACD日線來看,處于上漲趨勢,穩健的可以選擇觀望等待。空頭思路是因為目前EMA21均線和EMA55均線依然保持很遠,最近兩個月BTC上漲40%,而最近持續保持高位很快…

同時可視化原始中心點和經過坐標轉換后的中心點

std::vector<Eigen::Vector2d> centroids_unknown_motion_underk;std::vector<Eigen::Vector2d> measurements_centroids_unknown_motion_k= transformLandmarks(centroids_unknown_motion_k, weights_pose); // 數據填充 // k時刻經過轉換到k-1時刻坐標系下的中心…

Twincat使用:EtherCAT通信掃描硬件設備鏈接PLC變量

EtherCAT通信采用主從架構&#xff0c;其中一個主站設備負責整個EtherCAT網絡的管理和控制&#xff0c;而從站設備則負責在數據環網上傳遞數據。 主站設備可以是計算機、工控機、PLC等&#xff0c; 而從站設備可以是傳感器、執行器、驅動器等。 EL3102:MDP5001_300_CF8D1684;…

Arduino驅動PT100數字K型高溫傳感器(溫濕度傳感器)

目錄 1、傳感器特性 2、控制器和傳感器連線圖 3、硬件原理圖 4、驅動程序 PT100適用于大部分400℃以下高溫的測量,但是通常家用天然氣灶焰芯溫度可達800℃以上,燒制陶瓷的窖子或者大功率電爐溫度更可超過1000℃,在這些超高溫度的場景下就需要用到K型熱電偶。

C# 無法將“int[]“類型隱式轉換為“int?[]“,無法將“string[]“類型隱式轉換為“string?[]“

在 C# 中&#xff0c;不能將 int[] 隱式轉換為 int?[]&#xff0c;因為它們是兩種不同的類型。int[] 是一個整數數組&#xff0c;而 int?[] 是一個可空整數數組。要解決這個問題&#xff0c;你可以使用顯式轉換或創建一個新的可空整數數組。 兩種解決方案供大家選擇 // 示例…

C++編程——輸入

#include<bits/stdc.h> using namespace std; int main(){//beginint a 0, b 0, c 0, d 0, e 0;char f1, f2;char g[30];scanf("%d", &a); //輸入整數并賦值給變量ascanf("%d", &b); //輸入整數并賦值給變量bscanf("%d", &…

關于愛普生L3219彩色噴墨打印機打印過程中噪聲過大的幾點緩解方法

故障描述&#xff1a; 一臺新購買的愛普生L3219使用過程中出現了噪聲過大的問題&#xff0c;每次打印或者復印都或有明顯的噪音過大的現象&#xff0c;目測觀察大概是打印機字車左右來回移動的時候剮蹭滑道的問題&#xff0c;與經銷商溝通后由經銷商聯系上級供貨商更換一臺全新…

CAN實驗

CAN 寄存器 HAL庫函數 代碼 #include "./BSP/CAN/can.h"CAN_HandleTypeDef g_can1_handle; CAN_TxHeaderTypeDef g_can1_txheader; CAN_RxHeaderTypeDef g_can1_rxheader;/* STM32F103 TS1 8 TS2 7 BRP 3 波特率&#xff1a;36000 / [(9 8 1) * 4] 500Kbps …

Qt學習(2)

1.QObject 只有繼承了QObject類的類&#xff0c;才具有信號槽的能力。所以&#xff0c;為了使用信號槽&#xff0c;必須繼承QObject。凡是QObject類&#xff08;不管是直接子類還是間接子類&#xff09;&#xff0c;都應該在第一行代碼寫上Q_OBJECT。不管是不是使用信號槽&…

【Java 進階篇】Jedis 操作 String:Redis中的基礎數據類型

在Redis中&#xff0c;String是最基礎的數據類型之一&#xff0c;而Jedis作為Java開發者與Redis交互的利器&#xff0c;提供了豐富的API來操作String。本文將深入介紹Jedis如何操作Redis中的String類型數據&#xff0c;通過生動的代碼示例和詳細的解釋&#xff0c;讓你輕松掌握…

C# 中using關鍵字的使用

在C#中我們還是很有必要掌握using關鍵字的。 比如這樣&#xff1a; string path “D:\data.txt”; if (!File.Exists(path )) {File.Create(path); File.WriteAllText(path,"OK"); } 首先我創建…

正則表達式(Java)(韓順平筆記)

正則表達式&#xff08;Java&#xff09; 底層實現 package com.hspedu.RegExp;import java.util.regex.Matcher; import java.util.regex.Pattern;public class RegExp00 {public static void main(String[] args) {String content "1998年12月8日&#xff0c;第二代J…

【Promise】某個異步方法執行結束后 在執行下面方法

使用Promise &#xff0c;當 layer.msg(查詢成功) 這個方法執行結束后 &#xff0c;下面代碼才會執行 let thas this async function showMessage() {await new Promise(resolve > layer.msg(查詢成功, resolve));// 這里的代碼將在 layer.msg 執行結束后執行thas.isGuaran…

數字圖像處理(實踐篇)一 將圖像中的指定目標用bBox框起來吧!

目錄 一 實現方法 二 涉及的OpenCV函數 三 代碼 四 效果圖 一 實現方法 ①利用OTSU方法將前景與背景分割。 ②使用連通區域分析可以將具有相同像素值且位置相鄰的前景像素點組成的圖像區域識別。 ③畫bbox。 ④顯示結果。 二 涉及的OpenCV函數 ① OpenCV提供了cv2.th…

如何安裝和配置代理服務器squid?

安裝和配置Squid代理服務器通常需要幾個步驟。以下是在Ubuntu上安裝和配置Squid的簡單步驟&#xff1a; 步驟 1: 安裝Squid 打開終端&#xff0c;并使用以下命令安裝Squid&#xff1a; sudo apt update sudo apt install squid步驟 2: 配置Squid 默認配置文件位于 /etc/squ…

convertRect:toView 方法注意事項

這是在網上找到的一張圖 我們開發中有時候會用到左邊轉換&#xff0c;convertRect:toView 通常情況下&#xff0c;我們回這樣使用 CGRect newRect [a convertRect:originframe toView:c];其中newRect和 originframe的size相同&#xff0c;只改變origin newRect.origin a…