Java虚拟机简单介绍
安裝jdk之后一般都會安裝jre,在jre中就包含有Java虛擬機(jvm).
jvm是虛擬出來的,類似于簡單的系統,有自己的內存管理,寄存器,程序計數器cp,環境指針和棧指針等。
1.先說Java虛擬機的內存管理
?(1)寄存器
? ?JVM只設置了4個最為常用的寄存器。它們是:
? ?pc程序計數器,用于記錄程序的執行。
? ?optop操作數棧頂指針 ,記錄指向Java棧區的指針。
? ?frame當前執行環境指針, 記錄指向Java棧區的指針。
? ?vars指向當前執行環境中第一個局部變量的指針,記錄指向Java棧區的指針。
? ?所有寄存器均為32位。
?(2)jvm的棧結構
? 這個極為重要,對理解代碼底層。
? Java棧是JVM存儲信息的主要方法。Java代碼中一個任何類的每一個方法調用都會創建一個??蚣?#xff0c;以保存該方法的狀態信息。注意:這里面的棧框架是指不是一個棧結構, ? 而 是很多的棧結構。一般只要有{},就代表這一個棧結構?!皗” 進棧,“}”出棧。
? 是由一個一個的棧幀組成的后進先出的棧式結構,棧楨中存放方法運行時產生的局部變量、方法出口等信息。
? 當調用一個方法時,虛擬機棧中就會創建一個棧幀存放這些數據,當方法調用完成時,棧幀消失,如果方法中調用了其他方法,
? 則繼續在棧頂創建新的棧楨。
? 棧框架包括以下三類信息:
? 局部變量
? 局部變量用于存儲一個類的方法中所用到的局部變量。vars寄存器指向該變量表中的第一個局部變量。
? 每個Java方法使用一個固定大小的局部變量集。
? 執行環境
? 執行環境用于保存解釋器對Java字節碼進行解釋過程中所需的信息:上次調用的方法、局部變量指針和操作數棧的棧頂和棧底指針。
? 執行環境是一個執行一個方法的控制中心。例如:如果解釋器要執行iadd(整數加法),首先要從frame寄存器中找到當前執行環境,而后便從執行環境中找到操作數棧,從棧 ? 頂彈出兩個整數進行加法運算,最后將結果壓入棧頂。
? 操作數棧
? 用于存儲運算所需操作數及運算的結果
? (3)jvm 堆
? Java類的實例所需的存儲空間是在堆上分配的。解釋器負責分配,記錄,回收。
? 用于存放類的對象實例。
? (4)jvm存儲區,這個是最重要的,是jvm的軀干。任何數據的加載和方法的加載,都是從這個區域復制過去的。
? ?JVM有兩類存儲區:常量緩沖池和方法區。
? ?常量緩沖池用于存儲類名稱、方法和字段名稱以及串常量。
? ?方法區。在java的虛擬機中有一塊專門用來存放已經加載的類信息、常量、靜態變量以及方法代碼的內存區域
? ?方法區則用于存儲Java方法的字節碼。
? ?方法區提供加載的類的存儲,也是生命周期最長的,所以這里面也包含靜態變量的存儲,常量存儲。但是jvm存儲區還存在一個緩存區,這個緩存區就是加快一些數據和信息 ? ? ?的讀取工作,如字段,串常量(把字符串常量放到這里面,可以加快讀取工作)和類名稱。類名稱是必然要放到緩存區的,這樣可以很好的遍歷尋找類。方法也是如此。就相 ? 當于你有一個很大的數據表保存你的信息,但是你還需要一個索引記錄信息的名稱,關鍵字等信息,這樣可以提供你盡快從你的較大的數據表中讀取你要的數據。
?
2.jvm結構圖
3.jvm的類加載器
BootStrap ClassLoader:稱為啟動類加載器,是Java類加載層次中最頂層的類加載器,負責加載JDK中的核心類庫,如:rt.jar、resources.jar、charsets.jar等,可通過如下程序獲得該類加載器從哪些地方加載了相關的jar或class文件:
?
這是獲得jdk環境
System.out.println(System.getProperty("sun.boot.class.path"));這是獲取 根加載器路徑
Extension ClassLoader:稱為擴展類加載器,負責加載Java的擴展類庫,Java 虛擬機的實現會提供一個擴展庫目錄。該類加載器在此目錄里面查找并加載 Java 類。
默認加載JAVA_HOME/jre/lib/ext/目下的所有jar。
App ClassLoader:稱為系統類加載器,負責加載應用程序classpath目錄下的所有jar和class文件。一般來說,Java 應用的類都是由它來完成加載的??梢酝ㄟ^ ClassLoader.getSystemClassLoader()來獲取它。
?
除了系統提供的類加載器以外,開發人員可以通過繼承java.lang.ClassLoader類的方式實現自己的類加載器,以滿足一些特殊的需求。
除了引導類加載器之外,所有的類加載器都有一個父類加載器。 給出的 getParent()方法可以得到。對于?
系統提供的類加載器來說,系統類加載器的父類加載器是擴展類加載器,而擴展類加載器的父類加載器是引導類加載器;對于開發人員編寫的類加載器來說,其父類加載器是加載此類加載器 Java 類的類加載器。因為類加載器 Java 類如同其它的 Java 類一樣,也是要由類加載器來加載的。一般來說,開發人員編寫的類加載器的父類加載器是系統類加載器。類加載器通過這種方式組織起來,形成樹狀結構。樹的根節點就是引導類加載器。
4.程序運行
PC計數器:
每一個線程都擁有一個PC計數器,當線程啟動(start)時,PC計數器被創建,這個計數器存放當前正在被執行的字節碼指令(JVM指令)的地址。
Java棧:
同樣的,Java棧也是每個線程單獨擁有,線程啟動時創建。這個棧中存放著一系列的棧幀(Stack Frame),JVM只能進行壓入(Push)和彈出(Pop)棧幀這兩種操作。每當調用一個方法時,JVM就往棧里壓入一個棧幀,方法結束返回時彈出棧幀。如果方法執行時出現異常,可以調用printStackTrace等方法來查看棧的情況
5.jvm 底層實現的數據結構?
對象在堆中的存儲結構是hashtable, 每一個對象的hashcode 就是在hash表中查詢的key值。
在常量區中,所有的類字節碼文件中的字符信息存儲到方法區中的常量池中,常量池也是一個hash表。
在方法區中類對象的存儲結構也是hash表,reference堆上面的句柄池也是hash表。
?
總結
以上是生活随笔為你收集整理的Java虚拟机简单介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果xr红色为什么是特别版(苹果官网报价
- 下一篇: android中showSoftInpu